Skip to content

Commit db85add

Browse files
Fix the resource_api to fix tests
Signed-off-by: Gavin Didrichsen <[email protected]>
1 parent b26fdad commit db85add

File tree

1 file changed

+80
-28
lines changed

1 file changed

+80
-28
lines changed

lib/puppet/resource_api.rb

Lines changed: 80 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
require 'puppet/resource_api/glue'
66
require 'puppet/resource_api/parameter'
77
require 'puppet/resource_api/property'
8+
require 'puppet/resource_api/provider_get_cache'
89
require 'puppet/resource_api/puppet_context' unless RUBY_PLATFORM == 'java'
910
require 'puppet/resource_api/read_only_parameter'
1011
require 'puppet/resource_api/transport'
@@ -69,6 +70,15 @@ def type_definition
6970
apply_to_device
7071
end
7172

73+
define_singleton_method(:rsapi_provider_get_cache) do
74+
# This gives a new cache per resource provider on each Puppet run:
75+
@rsapi_provider_get_cache ||= Puppet::ResourceApi::ProviderGetCache.new
76+
end
77+
78+
def rsapi_provider_get_cache
79+
self.class.rsapi_provider_get_cache
80+
end
81+
7282
def initialize(attributes)
7383
# $stderr.puts "A: #{attributes.inspect}"
7484
if attributes.is_a? Puppet::Resource
@@ -154,8 +164,18 @@ def generate
154164
end
155165

156166
def rsapi_current_state
157-
refresh_current_state unless @rsapi_current_state
158-
@rsapi_current_state
167+
return @rsapi_current_state if @rsapi_current_state
168+
169+
# If the current state is not set, then check the cache and, if a value is
170+
# found, ensure it passes strict_check before allowing it to be used:
171+
cached_value = rsapi_provider_get_cache.get(rsapi_title)
172+
strict_check(cached_value) if cached_value
173+
@rsapi_current_state = cached_value
174+
end
175+
176+
def rsapi_current_state=(value)
177+
rsapi_provider_get_cache.add(rsapi_title, value)
178+
@rsapi_current_state = value
159179
end
160180

161181
def to_resource
@@ -242,57 +262,89 @@ def to_resource_shim(resource)
242262
type_definition.create_attribute_in(self, name, param_or_property, parent, options)
243263
end
244264

265+
def self.rsapi_provider_get(names = nil)
266+
# If the cache has been marked as having all instances, then just return the
267+
# full contents or the filtered contents based on names:
268+
if rsapi_provider_get_cache.cached_all?
269+
return rsapi_provider_get_cache.all if names.nil?
270+
271+
# If we have all instances cached but need specific ones, filter from cache
272+
cached_resources = names.map { |name| rsapi_provider_get_cache.get(name) }.compact
273+
return cached_resources unless cached_resources.empty?
274+
end
275+
276+
# For simple_get_filter, if we're asking for specific resources and they're cached, return those
277+
if type_definition.feature?('simple_get_filter') && !names.nil?
278+
cached_resources = names.map { |name| rsapi_provider_get_cache.get(name) }.compact
279+
return cached_resources if names.length == cached_resources.length
280+
end
281+
282+
fetched = if type_definition.feature?('simple_get_filter')
283+
my_provider.get(context, names)
284+
else
285+
my_provider.get(context)
286+
end
287+
288+
fetched.each do |resource_hash|
289+
type_definition.check_schema(resource_hash)
290+
rsapi_provider_get_cache.add(build_title(type_definition, resource_hash), resource_hash)
291+
end
292+
293+
if names.nil? && !type_definition.feature?('simple_get_filter')
294+
# Mark the cache as having all possible instances:
295+
rsapi_provider_get_cache.cached_all
296+
end
297+
298+
fetched
299+
end
300+
245301
def self.instances
246302
# puts 'instances'
247303
# force autoloading of the provider
248304
provider(type_definition.name)
249305

250-
initial_fetch = if type_definition.feature?('simple_get_filter')
251-
my_provider.get(context, [])
252-
else
253-
my_provider.get(context)
254-
end
255-
256-
initial_fetch.map do |resource_hash|
257-
type_definition.check_schema(resource_hash)
306+
rsapi_provider_get.map do |resource_hash|
258307
# allow a :title from the provider to override the default
259308
result = if resource_hash.key? :title
260309
new(title: resource_hash[:title])
261310
else
262311
new(title: build_title(type_definition, resource_hash))
263312
end
313+
# Cache the state in the generated resource, but unfortunately
314+
# this only benefits "puppet resource", not apply runs:
264315
result.cache_current_state(resource_hash)
265316
result
266317
end
267318
end
268319

269320
def refresh_current_state
270-
@rsapi_current_state = if type_definition.feature?('simple_get_filter')
271-
my_provider.get(context, [rsapi_title]).find { |h| namevar_match?(h) }
272-
else
273-
my_provider.get(context).find { |h| namevar_match?(h) }
274-
end
275-
276-
if @rsapi_current_state
277-
type_definition.check_schema(@rsapi_current_state)
278-
strict_check(@rsapi_current_state)
321+
current_state = self.class.rsapi_provider_get([rsapi_title]).find { |h| namevar_match?(h) }
322+
323+
if current_state
324+
strict_check(current_state)
279325
else
280-
@rsapi_current_state = if rsapi_title.is_a? Hash
281-
rsapi_title.dup
282-
else
283-
{ title: rsapi_title }
284-
end
285-
@rsapi_current_state[:ensure] = :absent if type_definition.ensurable?
326+
current_state = if rsapi_title.is_a? Hash
327+
rsapi_title.dup
328+
else
329+
{ title: rsapi_title }
330+
end
331+
current_state[:ensure] = :absent if type_definition.ensurable?
286332
end
333+
self.rsapi_current_state = current_state
287334
end
288335

289-
# Use this to set the current state from the `instances` method
336+
# Use this to set the current state from the `instances` method. "puppet resources"
337+
# needs this to minimize provider get() calls, but during a Puppet apply run
338+
# the instances() method is only used by resource generation, and resource
339+
# generators use and then discard the resources created by `instances``, so this
340+
# does not help with that:
290341
def cache_current_state(resource_hash)
291-
@rsapi_current_state = resource_hash
292-
strict_check(@rsapi_current_state)
342+
self.rsapi_current_state = resource_hash
343+
strict_check(resource_hash)
293344
end
294345

295346
def retrieve
347+
refresh_current_state unless rsapi_current_state
296348
Puppet.debug("Current State: #{rsapi_current_state.inspect}")
297349

298350
result = Puppet::Resource.new(self.class, title, parameters: rsapi_current_state)

0 commit comments

Comments
 (0)