poise 2.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 +7 -0
- data/.gitignore +10 -0
- data/.kitchen.travis.yml +9 -0
- data/.kitchen.yml +18 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +25 -0
- data/.yardopts +5 -0
- data/Berksfile +26 -0
- data/Berksfile.lock +10 -0
- data/CHANGELOG.md +58 -0
- data/Gemfile +32 -0
- data/LICENSE +202 -0
- data/README.md +198 -0
- data/Rakefile +17 -0
- data/lib/poise.rb +71 -0
- data/lib/poise/error.rb +24 -0
- data/lib/poise/helpers.rb +33 -0
- data/lib/poise/helpers/chefspec_matchers.rb +92 -0
- data/lib/poise/helpers/defined_in.rb +111 -0
- data/lib/poise/helpers/fused.rb +127 -0
- data/lib/poise/helpers/include_recipe.rb +62 -0
- data/lib/poise/helpers/inversion.rb +374 -0
- data/lib/poise/helpers/inversion/options_provider.rb +41 -0
- data/lib/poise/helpers/inversion/options_resource.rb +101 -0
- data/lib/poise/helpers/lazy_default.rb +62 -0
- data/lib/poise/helpers/lwrp_polyfill.rb +96 -0
- data/lib/poise/helpers/notifying_block.rb +78 -0
- data/lib/poise/helpers/option_collector.rb +117 -0
- data/lib/poise/helpers/resource_name.rb +99 -0
- data/lib/poise/helpers/subcontext_block.rb +58 -0
- data/lib/poise/helpers/subresources.rb +29 -0
- data/lib/poise/helpers/subresources/child.rb +217 -0
- data/lib/poise/helpers/subresources/container.rb +165 -0
- data/lib/poise/helpers/subresources/default_containers.rb +73 -0
- data/lib/poise/helpers/template_content.rb +165 -0
- data/lib/poise/provider.rb +55 -0
- data/lib/poise/resource.rb +75 -0
- data/lib/poise/subcontext.rb +27 -0
- data/lib/poise/subcontext/resource_collection.rb +56 -0
- data/lib/poise/subcontext/runner.rb +50 -0
- data/lib/poise/utils.rb +60 -0
- data/lib/poise/utils/resource_provider_mixin.rb +53 -0
- data/lib/poise/version.rb +20 -0
- data/poise.gemspec +38 -0
- data/test/cookbooks/poise_test/attributes/default.rb +17 -0
- data/test/cookbooks/poise_test/libraries/app.rb +43 -0
- data/test/cookbooks/poise_test/libraries/app_config.rb +46 -0
- data/test/cookbooks/poise_test/libraries/inversion.rb +67 -0
- data/test/cookbooks/poise_test/metadata.rb +18 -0
- data/test/cookbooks/poise_test/recipes/default.rb +25 -0
- data/test/cookbooks/poise_test/recipes/inversion.rb +42 -0
- data/test/gemfiles/chef-12.0.gemfile +18 -0
- data/test/gemfiles/chef-12.1.gemfile +18 -0
- data/test/gemfiles/chef-12.2.gemfile +18 -0
- data/test/gemfiles/chef-12.gemfile +18 -0
- data/test/gemfiles/master.gemfile +20 -0
- data/test/integration/default/serverspec/default_spec.rb +35 -0
- data/test/integration/default/serverspec/inversion_spec.rb +43 -0
- data/test/spec/helpers/chefspec_matchers_spec.rb +45 -0
- data/test/spec/helpers/defined_in_spec.rb +62 -0
- data/test/spec/helpers/fused_spec.rb +92 -0
- data/test/spec/helpers/include_recipe_spec.rb +34 -0
- data/test/spec/helpers/inversion/options_resource_spec.rb +212 -0
- data/test/spec/helpers/inversion_spec.rb +273 -0
- data/test/spec/helpers/lazy_default_spec.rb +74 -0
- data/test/spec/helpers/lwrp_polyfill_spec.rb +128 -0
- data/test/spec/helpers/notifying_block_spec.rb +87 -0
- data/test/spec/helpers/option_collector_spec.rb +82 -0
- data/test/spec/helpers/resource_name_spec.rb +39 -0
- data/test/spec/helpers/subcontext_block_spec.rb +94 -0
- data/test/spec/helpers/subresources/child_spec.rb +339 -0
- data/test/spec/helpers/subresources/container_spec.rb +175 -0
- data/test/spec/helpers/template_context_spec.rb +147 -0
- data/test/spec/poise_spec.rb +185 -0
- data/test/spec/provider_spec.rb +28 -0
- data/test/spec/resource_spec.rb +85 -0
- data/test/spec/spec_helper.rb +18 -0
- data/test/spec/utils/resource_provider_mixin_spec.rb +52 -0
- data/test/spec/utils_spec.rb +110 -0
- metadata +190 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module Poise
|
19
|
+
module Helpers
|
20
|
+
module Subresources
|
21
|
+
# Helpers to track default container resources. This is used to find a
|
22
|
+
# default parent for a child with no parent set. It flat out violates
|
23
|
+
# encapsulation to allow for the use of default parents to act as
|
24
|
+
# system-level defaults even when created in a nested scope.
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 2.0.0
|
28
|
+
module DefaultContainers
|
29
|
+
# Mutex to sync access to the containers array.
|
30
|
+
#
|
31
|
+
# @see .containers
|
32
|
+
CONTAINER_MUTEX = Mutex.new
|
33
|
+
|
34
|
+
# Add a resource to the array of default containers.
|
35
|
+
#
|
36
|
+
# @param resource [Chef::Resource] Resource to add.
|
37
|
+
# @param run_context [Chef::RunContext] Context of the current run.
|
38
|
+
# @return [void]
|
39
|
+
def self.register!(resource, run_context)
|
40
|
+
CONTAINER_MUTEX.synchronize do
|
41
|
+
containers(run_context) << resource
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Find a default container for a resource class.
|
46
|
+
#
|
47
|
+
# @param klass [Class] Resource class to search for.
|
48
|
+
# @param run_context [Chef::RunContext] Context of the current run.
|
49
|
+
# @return [Chef::Resource]
|
50
|
+
def self.find(klass, run_context)
|
51
|
+
CONTAINER_MUTEX.synchronize do
|
52
|
+
containers(run_context).reverse_each do |resource|
|
53
|
+
return resource if resource.is_a?(klass)
|
54
|
+
end
|
55
|
+
# Nothing found.
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Get the array of all default container resources.
|
63
|
+
#
|
64
|
+
# @note MUST BE CALLED FROM A LOCKED CONTEXT!
|
65
|
+
# @param run_context [Chef::RunContext] Context of the current run.
|
66
|
+
# @return [Array<Chef::Resource>]
|
67
|
+
def self.containers(run_context)
|
68
|
+
run_context.node.run_state[:poise_default_containers] ||= []
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'chef/provider/template_finder'
|
18
|
+
require 'chef/mixin/template'
|
19
|
+
|
20
|
+
require 'poise/helpers/lazy_default'
|
21
|
+
require 'poise/helpers/lwrp_polyfill'
|
22
|
+
require 'poise/helpers/option_collector'
|
23
|
+
require 'poise/utils'
|
24
|
+
|
25
|
+
|
26
|
+
module Poise
|
27
|
+
module Helpers
|
28
|
+
# A resource mixin to add a new kind of attribute, template content. TODO
|
29
|
+
#
|
30
|
+
# @since 1.0.0
|
31
|
+
module TemplateContent
|
32
|
+
include LazyDefault
|
33
|
+
include LWRPPolyfill
|
34
|
+
include OptionCollector
|
35
|
+
|
36
|
+
# @!classmethods
|
37
|
+
module ClassMethods
|
38
|
+
def attribute(name, options={})
|
39
|
+
if options.delete(:template)
|
40
|
+
name_prefix = name.empty? ? '' : "#{name}_"
|
41
|
+
|
42
|
+
# If you are reading this, I'm so sorry
|
43
|
+
# This is used for computing the default cookbook below
|
44
|
+
parent_filename = caller.first.reverse.split(':', 4).last.reverse
|
45
|
+
|
46
|
+
# If our parent class also declared a template_content attribute on the same name, inherit its options
|
47
|
+
if superclass.respond_to?("_#{name_prefix}_template_content_options")
|
48
|
+
options = superclass.send("_#{name_prefix}_template_content_options").merge(options)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Template source path if using a template
|
52
|
+
attribute("#{name_prefix}source", kind_of: String)
|
53
|
+
define_method("_#{name_prefix}source") do
|
54
|
+
send("#{name_prefix}source") || maybe_eval(options[:default_source])
|
55
|
+
end
|
56
|
+
|
57
|
+
# Template cookbook name if using a template
|
58
|
+
attribute("#{name_prefix}cookbook", kind_of: [String, Symbol], default: lazy do
|
59
|
+
if send("#{name_prefix}source")
|
60
|
+
cookbook_name
|
61
|
+
elsif options[:default_cookbook]
|
62
|
+
maybe_eval(options[:default_cookbook])
|
63
|
+
else
|
64
|
+
Poise::Utils.find_cookbook_name(run_context, parent_filename)
|
65
|
+
end
|
66
|
+
end)
|
67
|
+
|
68
|
+
# Template variables if using a template
|
69
|
+
attribute("#{name_prefix}options", option_collector: true)
|
70
|
+
|
71
|
+
# The big one, get/set content, but if you are getting and no
|
72
|
+
# explicit content was given, try to render the template
|
73
|
+
define_method("#{name_prefix}content") do |arg=nil, no_compute=false|
|
74
|
+
ret = set_or_return("#{name_prefix}content", arg, kind_of: String)
|
75
|
+
if !ret && !arg && !no_compute
|
76
|
+
ret = send("_#{name_prefix}content")
|
77
|
+
# Cache the results for next time
|
78
|
+
set_or_return("#{name_prefix}content", ret, {}) if ret
|
79
|
+
end
|
80
|
+
ret
|
81
|
+
end
|
82
|
+
|
83
|
+
# Validate that arguments work
|
84
|
+
define_method("_#{name_prefix}validate") do
|
85
|
+
if options[:required] && !send("_#{name_prefix}source") && !send("#{name_prefix}content", nil, true)
|
86
|
+
raise Chef::Exceptions::ValidationFailed, "#{self}: One of #{name_prefix}source or #{name_prefix}content is required"
|
87
|
+
end
|
88
|
+
if send("#{name_prefix}source") && send("#{name_prefix}content", nil, true)
|
89
|
+
raise Chef::Exceptions::ValidationFailed, "#{self}: Only one of #{name_prefix}source or #{name_prefix}content can be specified"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Monkey patch #after_create to run best-effort validation. Arguments
|
94
|
+
# could be changed after creation, but this gives nicer errors for
|
95
|
+
# most cases.
|
96
|
+
unless options[:no_validate_on_create]
|
97
|
+
old_after_created = instance_method(:after_created)
|
98
|
+
define_method(:after_created) do
|
99
|
+
old_after_created.bind(self).call
|
100
|
+
send("_#{name_prefix}validate")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Compile the needed content
|
105
|
+
define_method("_#{name_prefix}content") do
|
106
|
+
# Run validation again
|
107
|
+
send("_#{name_prefix}validate")
|
108
|
+
# Get all the relevant parameters
|
109
|
+
content = send("#{name_prefix}content", nil, true)
|
110
|
+
source = send("_#{name_prefix}source")
|
111
|
+
if content
|
112
|
+
content # I don't think it can ever hit this branch
|
113
|
+
elsif source
|
114
|
+
cookbook = send("#{name_prefix}cookbook")
|
115
|
+
template_options = send("#{name_prefix}options")
|
116
|
+
send("_#{name_prefix}render_template", source, cookbook, template_options)
|
117
|
+
else
|
118
|
+
maybe_eval(options[:default])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Actually render a template
|
123
|
+
define_method("_#{name_prefix}render_template") do |source, cookbook, template_options|
|
124
|
+
all_template_options = {}
|
125
|
+
all_template_options.update(maybe_eval(options[:default_options])) if options[:default_options]
|
126
|
+
all_template_options.update(template_options)
|
127
|
+
all_template_options[:new_resource] = self
|
128
|
+
finder = Chef::Provider::TemplateFinder.new(run_context, cookbook, node)
|
129
|
+
context = Chef::Mixin::Template::TemplateContext.new(all_template_options)
|
130
|
+
context[:node] = node
|
131
|
+
context[:template_finder] = finder
|
132
|
+
context.render_template(finder.find(source))
|
133
|
+
end
|
134
|
+
|
135
|
+
# Used to check if a parent class already defined a template_content thing here
|
136
|
+
define_singleton_method("_#{name_prefix}_template_content_options") do
|
137
|
+
options
|
138
|
+
end
|
139
|
+
else
|
140
|
+
super if defined?(super)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def included(klass)
|
145
|
+
super
|
146
|
+
klass.extend(ClassMethods)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
extend ClassMethods
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
# Evaluate lazy blocks if needed
|
155
|
+
def maybe_eval(val)
|
156
|
+
if val.is_a?(Chef::DelayedEvaluator)
|
157
|
+
instance_eval(&val)
|
158
|
+
else
|
159
|
+
val
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise/helpers'
|
18
|
+
|
19
|
+
|
20
|
+
module Poise
|
21
|
+
# Master provider mixin for Poise-based providers.
|
22
|
+
#
|
23
|
+
# @since 1.0.0
|
24
|
+
# @example Default helpers.
|
25
|
+
# class MyProvider < Chef::Provider
|
26
|
+
# include Poise::Provider
|
27
|
+
# end
|
28
|
+
# @example With optional helpers.
|
29
|
+
# class MyProvider < Chef::Provider
|
30
|
+
# include Poise::Provider
|
31
|
+
# poise_inversion(MyResource)
|
32
|
+
# end
|
33
|
+
module Provider
|
34
|
+
include Poise::Helpers::DefinedIn
|
35
|
+
include Poise::Helpers::IncludeRecipe
|
36
|
+
include Poise::Helpers::LWRPPolyfill
|
37
|
+
include Poise::Helpers::NotifyingBlock
|
38
|
+
|
39
|
+
# @!classmethods
|
40
|
+
module ClassMethods
|
41
|
+
def poise_inversion(resource, attribute=nil)
|
42
|
+
include Poise::Helpers::Inversion
|
43
|
+
inversion_resource(resource)
|
44
|
+
inversion_attribute(attribute) if attribute
|
45
|
+
end
|
46
|
+
|
47
|
+
def included(klass)
|
48
|
+
super
|
49
|
+
klass.extend(ClassMethods)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
extend ClassMethods
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise/helpers'
|
18
|
+
|
19
|
+
|
20
|
+
module Poise
|
21
|
+
# Master resource mixin for Poise-based resources.
|
22
|
+
#
|
23
|
+
# @since 1.0.0
|
24
|
+
# @example Default helpers.
|
25
|
+
# class MyResource < Chef::Resource
|
26
|
+
# include Poise::Resource
|
27
|
+
# end
|
28
|
+
# @example With optional helpers.
|
29
|
+
# class MyResource < Chef::Resource
|
30
|
+
# include Poise::Resource
|
31
|
+
# poise_subresource(MyParent)
|
32
|
+
# poise_fused
|
33
|
+
# end
|
34
|
+
module Resource
|
35
|
+
include Poise::Helpers::ChefspecMatchers
|
36
|
+
include Poise::Helpers::DefinedIn
|
37
|
+
include Poise::Helpers::LazyDefault
|
38
|
+
include Poise::Helpers::LWRPPolyfill
|
39
|
+
include Poise::Helpers::OptionCollector
|
40
|
+
include Poise::Helpers::ResourceName
|
41
|
+
include Poise::Helpers::TemplateContent
|
42
|
+
|
43
|
+
# @!classmethods
|
44
|
+
module ClassMethods
|
45
|
+
def poise_subresource_container(namespace=nil)
|
46
|
+
include Poise::Helpers::Subresources::Container
|
47
|
+
# false is a valid value.
|
48
|
+
container_namespace(namespace) unless namespace.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def poise_subresource(parent_type=nil, parent_optional=nil, parent_auto=nil)
|
52
|
+
include Poise::Helpers::Subresources::Child
|
53
|
+
parent_type(parent_type) if parent_type
|
54
|
+
parent_optional(parent_optional) unless parent_optional.nil?
|
55
|
+
parent_auto(parent_auto) unless parent_auto.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def poise_fused
|
59
|
+
include Poise::Helpers::Fused
|
60
|
+
end
|
61
|
+
|
62
|
+
def poise_inversion(options_resource=nil)
|
63
|
+
include Poise::Helpers::Inversion
|
64
|
+
inversion_options_resource(true) unless options_resource == false
|
65
|
+
end
|
66
|
+
|
67
|
+
def included(klass)
|
68
|
+
super
|
69
|
+
klass.extend(ClassMethods)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
extend ClassMethods
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module Poise
|
19
|
+
# Helpers and whatnot for dealing with subcontexts.
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 2.0.0
|
23
|
+
module Subcontext
|
24
|
+
autoload :ResourceCollection, 'poise/subcontext/resource_collection'
|
25
|
+
autoload :Runner, 'poise/subcontext/runner'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013-2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'chef/resource_collection'
|
18
|
+
|
19
|
+
|
20
|
+
module Poise
|
21
|
+
module Subcontext
|
22
|
+
# A subclass of the normal Chef ResourceCollection that creates a partially
|
23
|
+
# isolated set of resources. Notifications and other resources lookups can
|
24
|
+
# propagate out to parent contexts but not back in. This is used to allow
|
25
|
+
# black-box resources that are still aware of things in upper contexts.
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 1.0.0
|
29
|
+
class ResourceCollection < Chef::ResourceCollection
|
30
|
+
attr_accessor :parent
|
31
|
+
|
32
|
+
def initialize(parent)
|
33
|
+
@parent = parent
|
34
|
+
super()
|
35
|
+
end
|
36
|
+
|
37
|
+
def lookup(resource)
|
38
|
+
super
|
39
|
+
rescue Chef::Exceptions::ResourceNotFound
|
40
|
+
@parent.lookup(resource)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Iterate and expand all nested contexts
|
44
|
+
def recursive_each(&block)
|
45
|
+
if @parent
|
46
|
+
if @parent.respond_to?(:recursive_each)
|
47
|
+
@parent.recursive_each(&block)
|
48
|
+
else
|
49
|
+
@parent.each(&block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
each(&block)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|