test-kitchen 1.0.0.beta.4 → 1.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -1
- data/Gemfile +1 -1
- data/README.md +18 -7
- data/Rakefile +8 -1
- data/features/kitchen_init_command.feature +90 -11
- data/features/step_definitions/git_steps.rb +3 -0
- data/lib/kitchen/busser.rb +79 -45
- data/lib/kitchen/cli.rb +14 -13
- data/lib/kitchen/config.rb +79 -138
- data/lib/kitchen/data_munger.rb +224 -0
- data/lib/kitchen/driver/base.rb +4 -31
- data/lib/kitchen/driver/ssh_base.rb +6 -16
- data/lib/kitchen/driver.rb +4 -0
- data/lib/kitchen/generator/init.rb +20 -9
- data/lib/kitchen/instance.rb +53 -58
- data/lib/kitchen/lazy_hash.rb +50 -0
- data/lib/kitchen/platform.rb +2 -31
- data/lib/kitchen/provisioner/base.rb +55 -9
- data/lib/kitchen/provisioner/chef/berkshelf.rb +76 -0
- data/lib/kitchen/provisioner/chef/librarian.rb +72 -0
- data/lib/kitchen/provisioner/chef_base.rb +159 -78
- data/lib/kitchen/provisioner/chef_solo.rb +6 -36
- data/lib/kitchen/provisioner/chef_zero.rb +70 -59
- data/lib/kitchen/provisioner/dummy.rb +28 -0
- data/lib/kitchen/provisioner.rb +6 -4
- data/lib/kitchen/shell_out.rb +2 -5
- data/lib/kitchen/ssh.rb +1 -1
- data/lib/kitchen/suite.rb +10 -79
- data/lib/kitchen/util.rb +2 -2
- data/lib/kitchen/version.rb +2 -2
- data/lib/kitchen.rb +5 -0
- data/spec/kitchen/config_spec.rb +84 -123
- data/spec/kitchen/data_munger_spec.rb +1412 -0
- data/spec/kitchen/driver/base_spec.rb +30 -0
- data/spec/kitchen/instance_spec.rb +868 -86
- data/spec/kitchen/lazy_hash_spec.rb +63 -0
- data/spec/kitchen/platform_spec.rb +0 -22
- data/spec/kitchen/provisioner/base_spec.rb +210 -0
- data/spec/kitchen/provisioner_spec.rb +70 -0
- data/spec/kitchen/suite_spec.rb +25 -38
- data/spec/spec_helper.rb +1 -0
- data/support/chef-client-zero.rb +51 -35
- data/support/dummy-validation.pem +27 -0
- data/templates/init/kitchen.yml.erb +10 -22
- data/test-kitchen.gemspec +1 -2
- metadata +20 -18
data/lib/kitchen/cli.rb
CHANGED
@@ -43,7 +43,7 @@ module Kitchen
|
|
43
43
|
Kitchen.logger = Kitchen.default_file_logger
|
44
44
|
@config = Kitchen::Config.new(
|
45
45
|
:loader => Kitchen::Loader::YAML.new(ENV['KITCHEN_YAML']),
|
46
|
-
:log_level => ENV
|
46
|
+
:log_level => ENV.fetch('KITCHEN_LOG', "info").downcase.to_sym
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
@@ -52,7 +52,10 @@ module Kitchen
|
|
52
52
|
:desc => "List the name of each instance only, one per line"
|
53
53
|
method_option :debug, :aliases => "-d", :type => :boolean,
|
54
54
|
:desc => "Show computed driver configuration for each instance"
|
55
|
+
method_option :log_level, :aliases => "-l",
|
56
|
+
:desc => "Set the log level (debug, info, warn, error, fatal)"
|
55
57
|
def list(*args)
|
58
|
+
update_config!
|
56
59
|
result = parse_subcommand(args.first)
|
57
60
|
if options[:debug]
|
58
61
|
Array(result).each { |i| debug_instance(i) }
|
@@ -327,7 +330,7 @@ module Kitchen
|
|
327
330
|
[
|
328
331
|
color_pad(instance.name),
|
329
332
|
color_pad(instance.driver.name),
|
330
|
-
color_pad(
|
333
|
+
color_pad(instance.provisioner.name),
|
331
334
|
format_last_action(instance.last_action)
|
332
335
|
]
|
333
336
|
end
|
@@ -335,15 +338,17 @@ module Kitchen
|
|
335
338
|
def debug_instance(instance)
|
336
339
|
say "--------"
|
337
340
|
say "Instance: #{instance.name}"
|
338
|
-
say "Driver
|
339
|
-
say "Driver Config:"
|
341
|
+
say "Driver (#{instance.driver.name}):"
|
340
342
|
instance.driver.config_keys.sort.each do |key|
|
341
|
-
say " #{key}: #{instance.driver[key]}"
|
343
|
+
say " #{key}: #{instance.driver[key].inspect}"
|
342
344
|
end
|
343
|
-
|
344
|
-
|
345
|
-
say "
|
346
|
-
|
345
|
+
say "Provisioner (#{instance.provisioner.name}):"
|
346
|
+
instance.provisioner.config_keys.sort.each do |key|
|
347
|
+
say " #{key}: #{instance.provisioner[key].inspect}"
|
348
|
+
end
|
349
|
+
say "Busser (#{instance.busser.name}):"
|
350
|
+
instance.busser.config_keys.sort.each do |key|
|
351
|
+
say " #{key}: #{instance.busser[key].inspect}"
|
347
352
|
end
|
348
353
|
say ""
|
349
354
|
end
|
@@ -363,10 +368,6 @@ module Kitchen
|
|
363
368
|
end
|
364
369
|
end
|
365
370
|
|
366
|
-
def format_provisioner(name)
|
367
|
-
name.split('_').map { |word| word.capitalize }.join(' ')
|
368
|
-
end
|
369
|
-
|
370
371
|
def update_config!
|
371
372
|
if options[:log_level]
|
372
373
|
level = options[:log_level].downcase.to_sym
|
data/lib/kitchen/config.rb
CHANGED
@@ -16,8 +16,6 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
|
19
|
-
require 'vendor/hash_recursive_merge'
|
20
|
-
|
21
19
|
module Kitchen
|
22
20
|
|
23
21
|
# Base configuration class for Kitchen. This class exposes configuration such
|
@@ -26,193 +24,136 @@ module Kitchen
|
|
26
24
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
27
25
|
class Config
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
attr_reader :kitchen_root
|
28
|
+
attr_reader :log_root
|
29
|
+
attr_reader :test_base_path
|
30
|
+
attr_reader :loader
|
31
31
|
attr_accessor :log_level
|
32
|
-
attr_writer :platforms
|
33
|
-
attr_writer :suites
|
34
|
-
|
35
|
-
# Default driver plugin to use
|
36
|
-
DEFAULT_DRIVER_PLUGIN = "dummy".freeze
|
37
|
-
|
38
|
-
# Default provisioner to use
|
39
|
-
DEFAULT_PROVISIONER = "chef_solo".freeze
|
40
32
|
|
41
33
|
# Creates a new configuration.
|
42
34
|
#
|
43
35
|
# @param [Hash] options configuration
|
44
36
|
# @option options [#read] :loader
|
45
37
|
# @option options [String] :kitchen_root
|
38
|
+
# @option options [String] :log_root
|
46
39
|
# @option options [String] :test_base_path
|
47
40
|
# @option options [Symbol] :log_level
|
48
41
|
def initialize(options = {})
|
49
|
-
@loader = options
|
50
|
-
@kitchen_root = options
|
51
|
-
@
|
52
|
-
@
|
42
|
+
@loader = options.fetch(:loader) { Kitchen::Loader::YAML.new }
|
43
|
+
@kitchen_root = options.fetch(:kitchen_root) { Dir.pwd }
|
44
|
+
@log_level = options.fetch(:log_level) { Kitchen::DEFAULT_LOG_LEVEL }
|
45
|
+
@log_root = options.fetch(:log_root) { default_log_root }
|
46
|
+
@test_base_path = options.fetch(:test_base_path) { default_test_base_path }
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Array<Instance>] all instances, resulting from all platform and
|
50
|
+
# suite combinations
|
51
|
+
def instances
|
52
|
+
@instances ||= Collection.new(build_instances)
|
53
53
|
end
|
54
54
|
|
55
55
|
# @return [Array<Platform>] all defined platforms which will be used in
|
56
56
|
# convergence integration
|
57
57
|
def platforms
|
58
58
|
@platforms ||= Collection.new(
|
59
|
-
|
59
|
+
data.platform_data.map { |pdata| Platform.new(pdata) })
|
60
60
|
end
|
61
61
|
|
62
62
|
# @return [Array<Suite>] all defined suites which will be used in
|
63
63
|
# convergence integration
|
64
64
|
def suites
|
65
65
|
@suites ||= Collection.new(
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
# @return [Array<Instance>] all instances, resulting from all platform and
|
70
|
-
# suite combinations
|
71
|
-
def instances
|
72
|
-
@instances ||= build_instances
|
66
|
+
data.suite_data.map { |sdata| Suite.new(sdata) })
|
73
67
|
end
|
74
68
|
|
75
69
|
private
|
76
70
|
|
77
|
-
def new_suite(hash)
|
78
|
-
path_hash = {
|
79
|
-
:data_bags_path => calculate_path("data_bags", hash[:name], hash[:data_bags_path]),
|
80
|
-
:roles_path => calculate_path("roles", hash[:name], hash[:roles_path]),
|
81
|
-
:nodes_path => calculate_path("nodes", hash[:name], hash[:nodes_path]),
|
82
|
-
}
|
83
|
-
|
84
|
-
Suite.new(hash.rmerge(path_hash))
|
85
|
-
end
|
86
|
-
|
87
|
-
def new_platform(hash)
|
88
|
-
Platform.new(hash)
|
89
|
-
end
|
90
|
-
|
91
|
-
def new_driver(hash)
|
92
|
-
hash[:driver_config] ||= Hash.new
|
93
|
-
hash[:driver_config][:kitchen_root] = kitchen_root
|
94
|
-
hash[:driver_config][:provisioner] = hash[:provisioner]
|
95
|
-
|
96
|
-
Driver.for_plugin(hash[:driver_plugin], hash[:driver_config])
|
97
|
-
end
|
98
|
-
|
99
71
|
def build_instances
|
100
|
-
|
101
|
-
|
102
|
-
arr[0].excludes.include?(arr[1].name)
|
103
|
-
end
|
104
|
-
filtered_instances.each_with_index do |arr, index|
|
105
|
-
results << new_instance(arr[0], arr[1], index)
|
72
|
+
filter_instances.map.with_index do |(suite, platform), index|
|
73
|
+
new_instance(suite, platform, index)
|
106
74
|
end
|
107
|
-
Collection.new(results)
|
108
|
-
end
|
109
|
-
|
110
|
-
def new_instance(suite, platform, index)
|
111
|
-
platform_hash = platform_driver_hash(platform.name)
|
112
|
-
platform_hash[:driver_config].rmerge!(suite.driver_config)
|
113
|
-
driver = new_driver(merge_driver_hash(platform_hash))
|
114
|
-
provisioner = driver[:provisioner]
|
115
|
-
|
116
|
-
instance = Instance.new(
|
117
|
-
:suite => extend_suite(suite, provisioner),
|
118
|
-
:platform => extend_platform(platform, provisioner),
|
119
|
-
:driver => driver,
|
120
|
-
:logger => new_instance_logger(index)
|
121
|
-
)
|
122
|
-
extend_instance(instance, provisioner)
|
123
75
|
end
|
124
76
|
|
125
|
-
def
|
126
|
-
|
127
|
-
when /^chef_/ then suite.dup.extend(Suite::Cheflike)
|
128
|
-
when /^puppet_/ then suite.dup.extend(Suite::Puppetlike)
|
129
|
-
else suite.dup
|
130
|
-
end
|
77
|
+
def data
|
78
|
+
@data ||= DataMunger.new(loader.read, kitchen_config)
|
131
79
|
end
|
132
80
|
|
133
|
-
def
|
134
|
-
|
135
|
-
when /^chef_/ then platform.dup.extend(Platform::Cheflike)
|
136
|
-
else platform.dup
|
137
|
-
end
|
81
|
+
def default_log_root
|
82
|
+
File.join(kitchen_root, Kitchen::DEFAULT_LOG_DIR)
|
138
83
|
end
|
139
84
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
85
|
+
def default_test_base_path
|
86
|
+
File.join(kitchen_root, Kitchen::DEFAULT_TEST_DIR)
|
87
|
+
end
|
88
|
+
|
89
|
+
def filter_instances
|
90
|
+
suites.product(platforms).select do |suite, platform|
|
91
|
+
if !suite.includes.empty?
|
92
|
+
suite.includes.include?(platform.name)
|
93
|
+
elsif !suite.excludes.empty?
|
94
|
+
!suite.excludes.include?(platform.name)
|
95
|
+
else
|
96
|
+
true
|
97
|
+
end
|
145
98
|
end
|
146
99
|
end
|
147
100
|
|
148
|
-
def
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
def platform_driver_hash(platform_name)
|
153
|
-
h = data[:platforms].find { |p| p[:name] == platform_name } || Hash.new
|
154
|
-
h[:driver_config] ||= {}
|
155
|
-
|
156
|
-
h.select do |key, value|
|
157
|
-
[:driver_plugin, :driver_config, :provisioner].include?(key)
|
158
|
-
end
|
101
|
+
def instance_name(suite, platform)
|
102
|
+
Instance.name_for(suite, platform)
|
159
103
|
end
|
160
104
|
|
161
|
-
def
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
105
|
+
def kitchen_config
|
106
|
+
@kitchen_config ||= {
|
107
|
+
:defaults => {
|
108
|
+
:driver => Driver::DEFAULT_PLUGIN,
|
109
|
+
:provisioner => Provisioner::DEFAULT_PLUGIN
|
110
|
+
},
|
111
|
+
:kitchen_root => kitchen_root,
|
112
|
+
:test_base_path => test_base_path,
|
113
|
+
:log_level => log_level,
|
114
|
+
}
|
171
115
|
end
|
172
116
|
|
173
|
-
def
|
174
|
-
|
117
|
+
def new_busser(suite, platform)
|
118
|
+
bdata = data.busser_data_for(suite.name, platform.name)
|
119
|
+
Busser.new(suite.name, bdata)
|
175
120
|
end
|
176
121
|
|
177
|
-
def
|
178
|
-
|
122
|
+
def new_driver(suite, platform)
|
123
|
+
ddata = data.driver_data_for(suite.name, platform.name)
|
124
|
+
Driver.for_plugin(ddata[:name], ddata)
|
179
125
|
end
|
180
126
|
|
181
|
-
def
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
elsif File.directory?(common_path)
|
192
|
-
common_path
|
193
|
-
elsif File.directory?(top_level_path)
|
194
|
-
top_level_path
|
195
|
-
else
|
196
|
-
nil
|
197
|
-
end
|
127
|
+
def new_instance(suite, platform, index)
|
128
|
+
Instance.new(
|
129
|
+
:busser => new_busser(suite, platform),
|
130
|
+
:driver => new_driver(suite, platform),
|
131
|
+
:logger => new_logger(suite, platform, index),
|
132
|
+
:suite => suite,
|
133
|
+
:platform => platform,
|
134
|
+
:provisioner => new_provisioner(suite, platform),
|
135
|
+
:state_file => new_state_file(suite, platform)
|
136
|
+
)
|
198
137
|
end
|
199
138
|
|
200
|
-
def
|
201
|
-
|
202
|
-
|
203
|
-
:
|
204
|
-
:
|
205
|
-
|
139
|
+
def new_logger(suite, platform, index)
|
140
|
+
name = instance_name(suite, platform)
|
141
|
+
Logger.new(
|
142
|
+
:stdout => STDOUT,
|
143
|
+
:color => Color::COLORS[index % Color::COLORS.size].to_sym,
|
144
|
+
:logdev => File.join(log_root, "#{name}.log"),
|
145
|
+
:level => Util.to_logger_level(self.log_level),
|
146
|
+
:progname => name
|
147
|
+
)
|
206
148
|
end
|
207
149
|
|
208
|
-
def
|
209
|
-
data.
|
210
|
-
|
211
|
-
end
|
150
|
+
def new_provisioner(suite, platform)
|
151
|
+
pdata = data.provisioner_data_for(suite.name, platform.name)
|
152
|
+
Provisioner.for_plugin(pdata[:name], pdata)
|
212
153
|
end
|
213
154
|
|
214
|
-
def
|
215
|
-
|
155
|
+
def new_state_file(suite, platform)
|
156
|
+
StateFile.new(kitchen_root, instance_name(suite, platform))
|
216
157
|
end
|
217
158
|
end
|
218
159
|
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2013, Fletcher Nichol
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'vendor/hash_recursive_merge'
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
|
23
|
+
# Class to handle recursive merging of configuration between platforms,
|
24
|
+
# suites, and common data.
|
25
|
+
#
|
26
|
+
# This object will mutate the data Hash passed into its constructor and so
|
27
|
+
# should not be reused or shared across threads.
|
28
|
+
#
|
29
|
+
# @author Fletcher Nichol <fnichol@nichol.ca>
|
30
|
+
class DataMunger
|
31
|
+
|
32
|
+
def initialize(data, kitchen_config = {})
|
33
|
+
@data = data
|
34
|
+
@kitchen_config = kitchen_config
|
35
|
+
convert_legacy_driver_format!
|
36
|
+
convert_legacy_chef_paths_format!
|
37
|
+
convert_legacy_require_chef_omnibus_format!
|
38
|
+
move_chef_data_to_provisioner!
|
39
|
+
end
|
40
|
+
|
41
|
+
def busser_data_for(suite, platform)
|
42
|
+
merged_data_for(:busser, suite, platform, :version).tap do |bdata|
|
43
|
+
set_kitchen_config_at!(bdata, :kitchen_root)
|
44
|
+
set_kitchen_config_at!(bdata, :test_base_path)
|
45
|
+
set_kitchen_config_at!(bdata, :log_level)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def driver_data_for(suite, platform)
|
50
|
+
merged_data_for(:driver, suite, platform).tap do |ddata|
|
51
|
+
set_kitchen_config_at!(ddata, :kitchen_root)
|
52
|
+
set_kitchen_config_at!(ddata, :test_base_path)
|
53
|
+
set_kitchen_config_at!(ddata, :log_level)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def platform_data
|
58
|
+
data.fetch(:platforms, [])
|
59
|
+
end
|
60
|
+
|
61
|
+
def provisioner_data_for(suite, platform)
|
62
|
+
merged_data_for(:provisioner, suite, platform).tap do |pdata|
|
63
|
+
set_kitchen_config_at!(pdata, :kitchen_root)
|
64
|
+
set_kitchen_config_at!(pdata, :test_base_path)
|
65
|
+
set_kitchen_config_at!(pdata, :log_level)
|
66
|
+
combine_arrays!(pdata, :run_list, :platform, :suite)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def suite_data
|
71
|
+
data.fetch(:suites, [])
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
attr_reader :data, :kitchen_config
|
77
|
+
|
78
|
+
def combine_arrays!(root, key, *namespaces)
|
79
|
+
if root.has_key?(key)
|
80
|
+
root[key] = namespaces.
|
81
|
+
map { |namespace| root.fetch(key).fetch(namespace, []) }.flatten.
|
82
|
+
compact
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def convert_legacy_chef_paths_format!
|
87
|
+
data.fetch(:suites, []).each do |suite|
|
88
|
+
%w{data data_bags environments nodes roles}.each do |key|
|
89
|
+
move_chef_data_to_provisioner_at!(suite, "#{key}_path".to_sym)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def convert_legacy_driver_format!
|
95
|
+
convert_legacy_driver_format_at!(data)
|
96
|
+
data.fetch(:platforms, []).each do |platform|
|
97
|
+
convert_legacy_driver_format_at!(platform)
|
98
|
+
end
|
99
|
+
data.fetch(:suites, []).each do |suite|
|
100
|
+
convert_legacy_driver_format_at!(suite)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def convert_legacy_driver_format_at!(root)
|
105
|
+
if root.has_key?(:driver_config)
|
106
|
+
ddata = root.fetch(:driver, Hash.new)
|
107
|
+
ddata = { :name => ddata } if ddata.is_a?(String)
|
108
|
+
root[:driver] = root.delete(:driver_config).rmerge(ddata)
|
109
|
+
end
|
110
|
+
|
111
|
+
if root.has_key?(:driver_plugin)
|
112
|
+
ddata = root.fetch(:driver, Hash.new)
|
113
|
+
ddata = { :name => ddata } if ddata.is_a?(String)
|
114
|
+
root[:driver] = { :name => root.delete(:driver_plugin) }.rmerge(ddata)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def convert_legacy_require_chef_omnibus_format!
|
119
|
+
convert_legacy_require_chef_omnibus_format_at!(data)
|
120
|
+
data.fetch(:platforms, []).each do |platform|
|
121
|
+
convert_legacy_require_chef_omnibus_format_at!(platform)
|
122
|
+
end
|
123
|
+
data.fetch(:suites, []).each do |suite|
|
124
|
+
convert_legacy_require_chef_omnibus_format_at!(suite)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def convert_legacy_require_chef_omnibus_format_at!(root)
|
129
|
+
key = :require_chef_omnibus
|
130
|
+
ddata = root.fetch(:driver, Hash.new)
|
131
|
+
|
132
|
+
if ddata.is_a?(Hash) && ddata.has_key?(key)
|
133
|
+
pdata = root.fetch(:provisioner, Hash.new)
|
134
|
+
pdata = { :name => pdata } if pdata.is_a?(String)
|
135
|
+
root[:provisioner] =
|
136
|
+
{ key => root.fetch(:driver).delete(key) }.rmerge(pdata)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def merged_data_for(key, suite, platform, default_key = :name)
|
141
|
+
ddata = normalized_default_data(key, default_key)
|
142
|
+
cdata = normalized_common_data(key, default_key)
|
143
|
+
pdata = normalized_platform_data(key, default_key, platform)
|
144
|
+
sdata = normalized_suite_data(key, default_key, suite)
|
145
|
+
|
146
|
+
ddata.rmerge(cdata.rmerge(pdata.rmerge(sdata)))
|
147
|
+
end
|
148
|
+
|
149
|
+
def move_chef_data_to_provisioner!
|
150
|
+
data.fetch(:suites, []).each do |suite|
|
151
|
+
move_chef_data_to_provisioner_at!(suite, :attributes)
|
152
|
+
move_chef_data_to_provisioner_at!(suite, :run_list)
|
153
|
+
end
|
154
|
+
|
155
|
+
data.fetch(:platforms, []).each do |platform|
|
156
|
+
move_chef_data_to_provisioner_at!(platform, :attributes)
|
157
|
+
move_chef_data_to_provisioner_at!(platform, :run_list)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def move_chef_data_to_provisioner_at!(root, key)
|
162
|
+
if root.has_key?(key)
|
163
|
+
pdata = root.fetch(:provisioner, Hash.new)
|
164
|
+
pdata = { :name => pdata } if pdata.is_a?(String)
|
165
|
+
if ! root.fetch(key, nil).nil?
|
166
|
+
root[:provisioner] = pdata.rmerge({ key => root.delete(key) })
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def namespace_array!(root, key, bucket)
|
172
|
+
root[key] = { bucket => root.fetch(key) } if root.has_key?(key)
|
173
|
+
end
|
174
|
+
|
175
|
+
def normalized_common_data(key, default_key)
|
176
|
+
cdata = data.fetch(key, Hash.new)
|
177
|
+
cdata = cdata.nil? ? Hash.new : cdata.dup
|
178
|
+
cdata = { default_key => cdata } if cdata.is_a?(String)
|
179
|
+
cdata
|
180
|
+
end
|
181
|
+
|
182
|
+
def normalized_default_data(key, default_key)
|
183
|
+
ddata = kitchen_config.fetch(:defaults, Hash.new).fetch(key, Hash.new).dup
|
184
|
+
ddata = { default_key => ddata } if ddata.is_a?(String)
|
185
|
+
ddata
|
186
|
+
end
|
187
|
+
|
188
|
+
def normalized_platform_data(key, default_key, platform)
|
189
|
+
pdata = platform_data_for(platform).fetch(key, Hash.new)
|
190
|
+
pdata = pdata.nil? ? Hash.new : pdata.dup
|
191
|
+
pdata = { default_key => pdata } if pdata.is_a?(String)
|
192
|
+
namespace_array!(pdata, :run_list, :platform)
|
193
|
+
pdata
|
194
|
+
end
|
195
|
+
|
196
|
+
def normalized_suite_data(key, default_key, suite)
|
197
|
+
sdata = suite_data_for(suite).fetch(key, Hash.new)
|
198
|
+
sdata = sdata.nil? ? Hash.new : sdata.dup
|
199
|
+
sdata = { default_key => sdata } if sdata.is_a?(String)
|
200
|
+
namespace_array!(sdata, :run_list, :suite)
|
201
|
+
sdata
|
202
|
+
end
|
203
|
+
|
204
|
+
def platform_data_for(name)
|
205
|
+
data.fetch(:platforms, Hash.new).find(lambda { Hash.new }) do |platform|
|
206
|
+
platform.fetch(:name, nil) == name
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def set_kitchen_config_at!(root, key)
|
211
|
+
kdata = data.fetch(:kitchen, Hash.new)
|
212
|
+
|
213
|
+
root.delete(key) if root.has_key?(key)
|
214
|
+
root[key] = kitchen_config.fetch(key) if kitchen_config.has_key?(key)
|
215
|
+
root[key] = kdata.fetch(key) if kdata.has_key?(key)
|
216
|
+
end
|
217
|
+
|
218
|
+
def suite_data_for(name)
|
219
|
+
data.fetch(:suites, Hash.new).find(lambda { Hash.new }) do |suite|
|
220
|
+
suite.fetch(:name, nil) == name
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|