chefspec 2.0.1 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chefspec.rb +30 -44
- data/lib/chefspec/api.rb +74 -0
- data/lib/chefspec/api/apt_package.rb +192 -0
- data/lib/chefspec/api/batch.rb +43 -0
- data/lib/chefspec/api/chef_gem.rb +191 -0
- data/lib/chefspec/api/cookbook_file.rb +166 -0
- data/lib/chefspec/api/cron.rb +80 -0
- data/lib/chefspec/api/deploy.rb +117 -0
- data/lib/chefspec/api/directory.rb +80 -0
- data/lib/chefspec/api/dpkg_package.rb +117 -0
- data/lib/chefspec/api/easy_install_package.rb +154 -0
- data/lib/chefspec/api/env.rb +117 -0
- data/lib/chefspec/api/erl_call.rb +43 -0
- data/lib/chefspec/api/execute.rb +43 -0
- data/lib/chefspec/api/file.rb +166 -0
- data/lib/chefspec/api/freebsd_package.rb +80 -0
- data/lib/chefspec/api/gem_package.rb +191 -0
- data/lib/chefspec/api/git.rb +117 -0
- data/lib/chefspec/api/group.rb +154 -0
- data/lib/chefspec/api/http_request.rb +228 -0
- data/lib/chefspec/api/ifconfig.rb +154 -0
- data/lib/chefspec/api/include_recipe.rb +26 -0
- data/lib/chefspec/api/ips_package.rb +117 -0
- data/lib/chefspec/api/link.rb +102 -0
- data/lib/chefspec/api/log.rb +43 -0
- data/lib/chefspec/api/macports_package.rb +154 -0
- data/lib/chefspec/api/mdadm.rb +117 -0
- data/lib/chefspec/api/mount.rb +192 -0
- data/lib/chefspec/api/notifications.rb +38 -0
- data/lib/chefspec/api/ohai.rb +43 -0
- data/lib/chefspec/api/package.rb +192 -0
- data/lib/chefspec/api/pacman_package.rb +155 -0
- data/lib/chefspec/api/portage_package.rb +155 -0
- data/lib/chefspec/api/powershell_script.rb +43 -0
- data/lib/chefspec/api/registry_key.rb +166 -0
- data/lib/chefspec/api/remote_directory.rb +120 -0
- data/lib/chefspec/api/remote_file.rb +166 -0
- data/lib/chefspec/api/render_file.rb +32 -0
- data/lib/chefspec/api/route.rb +80 -0
- data/lib/chefspec/api/rpm_package.rb +117 -0
- data/lib/chefspec/api/ruby_block.rb +37 -0
- data/lib/chefspec/api/script.rb +228 -0
- data/lib/chefspec/api/service.rb +246 -0
- data/lib/chefspec/api/smartos_package.rb +117 -0
- data/lib/chefspec/api/solaris_package.rb +80 -0
- data/lib/chefspec/api/subversion.rb +154 -0
- data/lib/chefspec/api/template.rb +166 -0
- data/lib/chefspec/api/user.rb +228 -0
- data/lib/chefspec/api/yum_package.rb +154 -0
- data/lib/chefspec/berkshelf.rb +37 -0
- data/lib/chefspec/deprecations.rb +151 -0
- data/lib/chefspec/errors.rb +99 -0
- data/lib/chefspec/expect_exception.rb +45 -0
- data/lib/chefspec/extensions/chef/client.rb +15 -0
- data/lib/chefspec/extensions/chef/conditional.rb +11 -0
- data/lib/chefspec/extensions/chef/data_query.rb +29 -0
- data/lib/chefspec/extensions/chef/lwrp_base.rb +44 -0
- data/lib/chefspec/extensions/chef/resource.rb +27 -0
- data/lib/chefspec/extensions/chef/securable.rb +19 -0
- data/lib/chefspec/formatter.rb +270 -0
- data/lib/chefspec/macros.rb +217 -0
- data/lib/chefspec/matchers.rb +9 -0
- data/lib/chefspec/matchers/include_recipe_matcher.rb +45 -0
- data/lib/chefspec/matchers/link_to_matcher.rb +28 -0
- data/lib/chefspec/matchers/notifications_matcher.rb +92 -0
- data/lib/chefspec/matchers/render_file_matcher.rb +72 -0
- data/lib/chefspec/matchers/resource_matcher.rb +143 -0
- data/lib/chefspec/renderer.rb +137 -0
- data/lib/chefspec/rspec.rb +17 -0
- data/lib/chefspec/runner.rb +274 -0
- data/lib/chefspec/stubs/command_registry.rb +11 -0
- data/lib/chefspec/stubs/command_stub.rb +37 -0
- data/lib/chefspec/stubs/data_bag_item_registry.rb +13 -0
- data/lib/chefspec/stubs/data_bag_item_stub.rb +25 -0
- data/lib/chefspec/stubs/data_bag_registry.rb +13 -0
- data/lib/chefspec/stubs/data_bag_stub.rb +23 -0
- data/lib/chefspec/stubs/registry.rb +32 -0
- data/lib/chefspec/stubs/search_registry.rb +13 -0
- data/lib/chefspec/stubs/search_stub.rb +25 -0
- data/lib/chefspec/stubs/stub.rb +37 -0
- data/lib/chefspec/version.rb +1 -2
- metadata +100 -103
- data/lib/chef/expect_exception.rb +0 -34
- data/lib/chef/formatters/chefspec.rb +0 -233
- data/lib/chef/knife/cookbook_create_specs.rb +0 -107
- data/lib/chefspec/chef_runner.rb +0 -275
- data/lib/chefspec/helpers/describe.rb +0 -17
- data/lib/chefspec/matchers/cron.rb +0 -7
- data/lib/chefspec/matchers/env.rb +0 -8
- data/lib/chefspec/matchers/execute.rb +0 -33
- data/lib/chefspec/matchers/file.rb +0 -83
- data/lib/chefspec/matchers/file_content.rb +0 -32
- data/lib/chefspec/matchers/group.rb +0 -8
- data/lib/chefspec/matchers/include_recipe.rb +0 -20
- data/lib/chefspec/matchers/link.rb +0 -14
- data/lib/chefspec/matchers/log.rb +0 -21
- data/lib/chefspec/matchers/notifications.rb +0 -43
- data/lib/chefspec/matchers/package.rb +0 -39
- data/lib/chefspec/matchers/python.rb +0 -7
- data/lib/chefspec/matchers/ruby_block.rb +0 -13
- data/lib/chefspec/matchers/script.rb +0 -34
- data/lib/chefspec/matchers/service.rb +0 -25
- data/lib/chefspec/matchers/shared.rb +0 -132
- data/lib/chefspec/matchers/user.rb +0 -8
- data/lib/chefspec/minitest.rb +0 -195
- data/lib/chefspec/monkey_patches/conditional.rb +0 -19
- data/lib/chefspec/monkey_patches/hash.rb +0 -23
- data/lib/chefspec/monkey_patches/lwrp_base.rb +0 -45
- data/lib/chefspec/monkey_patches/provider.rb +0 -43
@@ -0,0 +1,9 @@
|
|
1
|
+
module ChefSpec
|
2
|
+
module Matchers
|
3
|
+
require_relative 'matchers/include_recipe_matcher'
|
4
|
+
require_relative 'matchers/link_to_matcher'
|
5
|
+
require_relative 'matchers/notifications_matcher'
|
6
|
+
require_relative 'matchers/render_file_matcher'
|
7
|
+
require_relative 'matchers/resource_matcher'
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ChefSpec::Matchers
|
2
|
+
class IncludeRecipeMatcher
|
3
|
+
def initialize(recipe_name)
|
4
|
+
@recipe_name = with_default(recipe_name)
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(runner)
|
8
|
+
@runner = runner
|
9
|
+
loaded_recipes.include?(@recipe_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def description
|
13
|
+
"include recipe '#{@recipe_name}'"
|
14
|
+
end
|
15
|
+
|
16
|
+
def failure_message_for_should
|
17
|
+
"expected #{loaded_recipes} to include '#{@recipe_name}'"
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message_for_should_not
|
21
|
+
"expected '#{@recipe_name}' to not be included"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
#
|
26
|
+
# Automatically appends "+::default+" to recipes that need them.
|
27
|
+
#
|
28
|
+
# @param [String] name
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
def with_default(name)
|
33
|
+
name.include?('::') ? name : "#{name}::default"
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# The list of loaded recipes on the Chef run (normalized)
|
38
|
+
#
|
39
|
+
# @return [Array<String>]
|
40
|
+
#
|
41
|
+
def loaded_recipes
|
42
|
+
@runner.run_context.loaded_recipes.map { |name| with_default(name) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ChefSpec::Matchers
|
2
|
+
class LinkToMatcher
|
3
|
+
def initialize(path)
|
4
|
+
@path = path
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(link)
|
8
|
+
@link = link
|
9
|
+
@link.is_a?(Chef::Resource::Link) && @path === @link.to
|
10
|
+
end
|
11
|
+
|
12
|
+
def description
|
13
|
+
"link to '#{@path}'"
|
14
|
+
end
|
15
|
+
|
16
|
+
def failure_message_for_should
|
17
|
+
if @link.nil?
|
18
|
+
"expected 'link[#{@path}]' with action ':create' to be in Chef run"
|
19
|
+
else
|
20
|
+
"expected '#{@link}' to link to '#{@path}' but was '#{@link.to}'"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def failure_message_for_should_not
|
25
|
+
"expected '#{@link}' to not link to '#{@path}'"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module ChefSpec::Matchers
|
2
|
+
class NotificationsMatcher
|
3
|
+
def initialize(signature)
|
4
|
+
signature.match(/^([^\[]*)\[(.*)\]$/)
|
5
|
+
@expected_resource_type = $1
|
6
|
+
@expected_resource_name = $2
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(resource)
|
10
|
+
@resource = resource
|
11
|
+
|
12
|
+
block = Proc.new do |notified|
|
13
|
+
notified.resource.resource_name.to_s == @expected_resource_type &&
|
14
|
+
(@expected_resource_name === notified.resource.identity.to_s || @expected_resource_name === notified.resource.name.to_s) &&
|
15
|
+
matches_action?(notified)
|
16
|
+
end
|
17
|
+
|
18
|
+
if @immediately
|
19
|
+
immediate_notifications.any?(&block)
|
20
|
+
elsif @delayed
|
21
|
+
delayed_notifications.any?(&block)
|
22
|
+
else
|
23
|
+
all_notifications.any?(&block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to(action)
|
28
|
+
@action = action.to_sym
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def immediately
|
33
|
+
@immediately = true
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def delayed
|
38
|
+
@delayed = true
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def description
|
43
|
+
message = "notify #{@expected_resource_type}[#{@expected_resource_name}]"
|
44
|
+
message << " with action #{@action.inspect}" if @action
|
45
|
+
message << " immediately" if @immediately
|
46
|
+
message << " delayed" if @delayed
|
47
|
+
message
|
48
|
+
end
|
49
|
+
|
50
|
+
def failure_message_for_should
|
51
|
+
message = "expected '#{@resource.resource_name}[#{@resource.name}]' to notify '#{@expected_resource_type}[#{@expected_resource_name}]'"
|
52
|
+
message << " with action #{@action.inspect}" if @action
|
53
|
+
message << " immediately" if @immediately
|
54
|
+
message << " delayed" if @delayed
|
55
|
+
message << ", but did not."
|
56
|
+
message << "\n\n"
|
57
|
+
message << "Other notifications were:\n#{format_notifications}"
|
58
|
+
message
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def all_notifications
|
63
|
+
immediate_notifications + delayed_notifications
|
64
|
+
end
|
65
|
+
|
66
|
+
def immediate_notifications
|
67
|
+
@resource.immediate_notifications
|
68
|
+
end
|
69
|
+
|
70
|
+
def delayed_notifications
|
71
|
+
@resource.delayed_notifications
|
72
|
+
end
|
73
|
+
|
74
|
+
def matches_action?(notification)
|
75
|
+
return true if @action.nil?
|
76
|
+
@action == notification.action.to_sym
|
77
|
+
end
|
78
|
+
|
79
|
+
def format_notification(notification)
|
80
|
+
resource = notification.resource
|
81
|
+
type = notification.notifying_resource.immediate_notifications.include?(notification) ? :immediately : :delayed
|
82
|
+
|
83
|
+
"notifies :#{notification.action}, '#{resource.resource_name}[#{resource.name}]', :#{type}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def format_notifications
|
87
|
+
all_notifications.map do |notification|
|
88
|
+
' ' + format_notification(notification)
|
89
|
+
end.join("\n")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ChefSpec::Matchers
|
2
|
+
class RenderFileMatcher
|
3
|
+
def initialize(path)
|
4
|
+
@path = path
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(runner)
|
8
|
+
@runner = runner
|
9
|
+
resource && has_create_action? && matches_content?
|
10
|
+
end
|
11
|
+
|
12
|
+
def with_content(expected_content)
|
13
|
+
@expected_content = expected_content
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
"render file '#{@path}'"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_for_should
|
22
|
+
message = "expected Chef run to render '#{@path}'"
|
23
|
+
message << " with:\n\n#{@expected_content}\n\nbut got:\n\n#{@actual_content}" if @expected_content
|
24
|
+
message
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure_message_for_should_not
|
28
|
+
message = "expected file '#{@path}'"
|
29
|
+
message << " with:\n\n#{@expected_content}\n\n" if @expected_content
|
30
|
+
message << " to not be in Chef run"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def resource
|
35
|
+
@resource ||= @runner.find_resource(:cookbook_file, @path) ||
|
36
|
+
@runner.find_resource(:file, @path) ||
|
37
|
+
@runner.find_resource(:template, @path)
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Determines if the given resource has a create-like action.
|
42
|
+
#
|
43
|
+
# @param [Chef::Resource] resource
|
44
|
+
#
|
45
|
+
# @return [Boolean]
|
46
|
+
#
|
47
|
+
def has_create_action?
|
48
|
+
!([:create, :create_if_missing] & Array(resource.action).map(&:to_sym)).empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Determines if the resources content matches the expected content.
|
53
|
+
#
|
54
|
+
# @param [Chef::Resource] resource
|
55
|
+
#
|
56
|
+
# @return [Boolean]
|
57
|
+
#
|
58
|
+
def matches_content?
|
59
|
+
return true if @expected_content.nil?
|
60
|
+
|
61
|
+
@actual_content = ChefSpec::Renderer.new(@runner, resource).content
|
62
|
+
|
63
|
+
return false if @actual_content.nil?
|
64
|
+
|
65
|
+
if @expected_content.is_a?(Regexp)
|
66
|
+
@actual_content =~ @expected_content
|
67
|
+
else
|
68
|
+
@actual_content.include?(@expected_content)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module ChefSpec::Matchers
|
2
|
+
class ResourceMatcher
|
3
|
+
def initialize(resource_name, expected_action, expected_identity)
|
4
|
+
@resource_name = resource_name
|
5
|
+
@expected_action = expected_action
|
6
|
+
@expected_identity = expected_identity
|
7
|
+
end
|
8
|
+
|
9
|
+
def with(parameters = {})
|
10
|
+
params.merge!(parameters)
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Allow users to specify fancy #with matchers.
|
16
|
+
#
|
17
|
+
def method_missing(m, *args, &block)
|
18
|
+
if m.to_s =~ /^with_(.+)$/
|
19
|
+
with($1.to_sym => args.first)
|
20
|
+
self
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def matches?(runner)
|
27
|
+
@runner = runner
|
28
|
+
|
29
|
+
if resource
|
30
|
+
resource_actions.include?(@expected_action) && unmatched_parameters.empty?
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def failure_message_for_should
|
37
|
+
if resource
|
38
|
+
if resource_actions.include?(@expected_action)
|
39
|
+
"expected '#{resource.to_s}' to have parameters:" \
|
40
|
+
"\n\n" \
|
41
|
+
" " + unmatched_parameters.collect { |parameter, h|
|
42
|
+
"#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
|
43
|
+
}.join("\n ")
|
44
|
+
|
45
|
+
else
|
46
|
+
"expected '#{resource.to_s}' actions #{resource_actions.inspect}" \
|
47
|
+
" to include ':#{@expected_action}'"
|
48
|
+
end
|
49
|
+
else
|
50
|
+
"expected '#{@resource_name}[#{@expected_identity}]' with" \
|
51
|
+
" action ':#{@expected_action}' to be in Chef run. Other" \
|
52
|
+
" #{@resource_name} resources:" \
|
53
|
+
"\n\n" \
|
54
|
+
" " + similar_resources.map(&:to_s).join("\n ")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def failure_message_for_should_not
|
59
|
+
if resource
|
60
|
+
"expected '#{resource.to_s}' actions #{resource_actions.inspect} to not exist"
|
61
|
+
else
|
62
|
+
"expected '#{resource.to_s}' to not exist"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def description
|
67
|
+
"#{@expected_action} #{@resource_name}"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def unmatched_parameters
|
72
|
+
return @_unmatched_parameters if @_unmatched_parameters
|
73
|
+
|
74
|
+
@_unmatched_parameters = {}
|
75
|
+
|
76
|
+
params.each do |parameter, expected|
|
77
|
+
unless matches_parameter?(parameter, expected)
|
78
|
+
@_unmatched_parameters[parameter] = {
|
79
|
+
expected: expected,
|
80
|
+
actual: safe_send(parameter),
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
@_unmatched_parameters
|
86
|
+
end
|
87
|
+
|
88
|
+
def matches_parameter?(parameter, expected)
|
89
|
+
# Chef 11+ stores the source parameter internally as an Array
|
90
|
+
if parameter == :source
|
91
|
+
Array(expected) == Array(safe_send(parameter))
|
92
|
+
else
|
93
|
+
expected === safe_send(parameter)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def safe_send(parameter)
|
98
|
+
resource.send(parameter)
|
99
|
+
rescue NoMethodError
|
100
|
+
nil
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Any other resources in the Chef run that have the same resource
|
105
|
+
# type. Used by {failure_message} to be ultra helpful.
|
106
|
+
#
|
107
|
+
# @return [Array<Chef::Resource>]
|
108
|
+
#
|
109
|
+
def similar_resources
|
110
|
+
@_similar_resources ||= @runner.find_resources(@resource_name)
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Find the resource in the Chef run by the given class name and
|
115
|
+
# resource identity/name.
|
116
|
+
#
|
117
|
+
# @see ChefSpec::Runner#find_resource
|
118
|
+
#
|
119
|
+
# @return [Chef::Resource, nil]
|
120
|
+
#
|
121
|
+
def resource
|
122
|
+
@_resource ||= @runner.find_resource(@resource_name, @expected_identity)
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# The list of actions on this resource.
|
127
|
+
#
|
128
|
+
# @return [Array<Symbol>]
|
129
|
+
#
|
130
|
+
def resource_actions
|
131
|
+
@_resource_actions ||= Array(resource.action).map(&:to_sym)
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# The list of parameters passed to the {with} matcher.
|
136
|
+
#
|
137
|
+
# @return [Hash]
|
138
|
+
#
|
139
|
+
def params
|
140
|
+
@_params ||= {}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
begin
|
2
|
+
require 'chef/mixin/template'
|
3
|
+
require 'chef/provider/template_finder'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
|
7
|
+
module ChefSpec
|
8
|
+
class Renderer
|
9
|
+
# @return [Chef::Runner]
|
10
|
+
attr_reader :chef_run
|
11
|
+
|
12
|
+
# @return [Chef::Resource]
|
13
|
+
attr_reader :resource
|
14
|
+
|
15
|
+
#
|
16
|
+
# Create a new Renderer for the given Chef run and resource.
|
17
|
+
#
|
18
|
+
# @param [Chef::Runner] chef_run
|
19
|
+
# the Chef run containing the resources
|
20
|
+
# @param [Chef::Resource] resource
|
21
|
+
# the resource to render content from
|
22
|
+
#
|
23
|
+
def initialize(chef_run, resource)
|
24
|
+
@chef_run = chef_run
|
25
|
+
@resource = resource
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# The content of the resource (this method delegates to the)
|
30
|
+
# various private rendering methods.
|
31
|
+
#
|
32
|
+
# @return [String, nil]
|
33
|
+
# the contents of the file as a string, or nil if the resource
|
34
|
+
# does not contain or respond to a content renderer.
|
35
|
+
#
|
36
|
+
def content
|
37
|
+
case resource.resource_name.to_s
|
38
|
+
when 'template'
|
39
|
+
content_from_template(chef_run, resource)
|
40
|
+
when 'file'
|
41
|
+
content_from_file(chef_run, resource)
|
42
|
+
when 'cookbook_file'
|
43
|
+
content_from_cookbook_file(chef_run, resource)
|
44
|
+
else
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
#
|
51
|
+
# Compute the contents of a template using Chef's templating logic.
|
52
|
+
#
|
53
|
+
# @param [Chef::RunContext] chef_run
|
54
|
+
# the run context for the node
|
55
|
+
# @param [Chef::Provider::Template] template
|
56
|
+
# the template resource
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
#
|
60
|
+
def content_from_template(chef_run, template)
|
61
|
+
cookbook_name = template.cookbook || template.cookbook_name
|
62
|
+
template_location = cookbook_collection(chef_run.node)[cookbook_name].preferred_filename_on_disk_location(chef_run.node, :templates, template.source)
|
63
|
+
|
64
|
+
if Chef::Mixin::Template.const_defined?(:TemplateContext) # Chef 11+
|
65
|
+
template_context = Chef::Mixin::Template::TemplateContext.new([])
|
66
|
+
template_context.update({
|
67
|
+
:node => chef_run.node,
|
68
|
+
:template_finder => template_finder(chef_run, cookbook_name),
|
69
|
+
}.merge(template.variables))
|
70
|
+
template_context.render_template(template_location)
|
71
|
+
else
|
72
|
+
template.provider.new(template, chef_run.run_context).send(:render_with_context, template_location) do |file|
|
73
|
+
File.read(file.path)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Get the contents of a file resource.
|
80
|
+
#
|
81
|
+
# @param [Chef::RunContext] chef_run
|
82
|
+
# the run context for the node
|
83
|
+
# @param [Chef::Provider::File] file
|
84
|
+
# the file resource
|
85
|
+
#
|
86
|
+
# @return [String]
|
87
|
+
#
|
88
|
+
def content_from_file(chef_run, file)
|
89
|
+
file.content
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Get the contents of a cookbook file using Chef.
|
94
|
+
#
|
95
|
+
# @param [Chef::RunContext] chef_run
|
96
|
+
# the run context for the node
|
97
|
+
# @param [Chef::Provider::CookbookFile] cookbook_file
|
98
|
+
# the file resource
|
99
|
+
#
|
100
|
+
def content_from_cookbook_file(chef_run, cookbook_file)
|
101
|
+
cookbook_name = cookbook_file.cookbook || cookbook_file.cookbook_name
|
102
|
+
cookbook = cookbook_collection(chef_run.node)[cookbook_name]
|
103
|
+
File.read(cookbook.preferred_filename_on_disk_location(chef_run.node, :files, cookbook_file.source, cookbook_file.path))
|
104
|
+
end
|
105
|
+
|
106
|
+
# The cookbook collection for the current Chef run context. Handles
|
107
|
+
# the differing cases between Chef 10 and Chef 11.
|
108
|
+
#
|
109
|
+
# @param [Chef::Node] node
|
110
|
+
# the Chef node to get the cookbook collection from
|
111
|
+
#
|
112
|
+
# @return [Array<Chef::Cookbook>]
|
113
|
+
def cookbook_collection(node)
|
114
|
+
if node.respond_to?(:run_context)
|
115
|
+
node.run_context.cookbook_collection # Chef 11+
|
116
|
+
else
|
117
|
+
node.cookbook_collection # Chef 10
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return a new instance of the TemplateFinder if we are running on Chef 11.
|
122
|
+
#
|
123
|
+
# @param [Chef::RunContext] chef_run
|
124
|
+
# the run context for the noe
|
125
|
+
# @param [String] cookbook_name
|
126
|
+
# the name of the cookbook
|
127
|
+
#
|
128
|
+
# @return [Chef::Provider::TemplateFinder, nil]
|
129
|
+
def template_finder(chef_run, cookbook_name)
|
130
|
+
if Chef::Provider.const_defined?(:TemplateFinder) # Chef 11+
|
131
|
+
Chef::Provider::TemplateFinder.new(chef_run.run_context, cookbook_name, chef_run.node)
|
132
|
+
else
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|