lib/puppet/resource_api.rb in puppet-resource_api-1.4.2 vs lib/puppet/resource_api.rb in puppet-resource_api-1.5.0
- old
+ new
@@ -77,14 +77,25 @@
define_method(:initialize) do |attributes|
# $stderr.puts "A: #{attributes.inspect}"
if attributes.is_a? Puppet::Resource
@title = attributes.title
@catalog = attributes.catalog
+ sensitives = attributes.sensitive_parameters
attributes = attributes.to_hash
else
@ral_find_absent = true
+ sensitives = []
end
+
+ # undo puppet's unwrapping of Sensitive values to provide a uniform experience for providers
+ # See https://tickets.puppetlabs.com/browse/PDK-1091 for investigation and background
+ sensitives.each do |name|
+ if attributes.key?(name) && !attributes[name].is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
+ attributes[name] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(attributes[name])
+ end
+ end
+
# $stderr.puts "B: #{attributes.inspect}"
if type_definition.feature?('canonicalize')
attributes = my_provider.canonicalize(context, [attributes])[0]
end
@@ -186,13 +197,17 @@
defaultto :false # rubocop:disable Lint/BooleanSymbol
elsif options[:default] == true
# work around https://tickets.puppetlabs.com/browse/PUP-2368
defaultto :true # rubocop:disable Lint/BooleanSymbol
else
- defaultto options[:default]
+ # marshal the default option to decouple that from the actual value.
+ # we cache the dumped value in `marshalled`, but use a block to unmarshal
+ # everytime the value is requested. Objects that can't be marshalled
+ # See https://stackoverflow.com/a/8206537/4918
+ marshalled = Marshal.dump(options[:default])
+ defaultto { Marshal.load(marshalled) } # rubocop:disable Security/MarshalLoad
end
- # defaultto options[:default]
end
end
if name == :ensure
def insync?(is)
@@ -299,46 +314,57 @@
define_singleton_method(:instances) do
# puts 'instances'
# force autoloading of the provider
provider(type_definition.name)
- my_provider.get(context).map do |resource_hash|
+ initial_fetch = if type_definition.feature?('simple_get_filter')
+ my_provider.get(context, [])
+ else
+ my_provider.get(context)
+ end
+
+ initial_fetch.map do |resource_hash|
type_definition.check_schema(resource_hash)
- result = new(title: resource_hash[type_definition.namevars.first])
+ # allow a :title from the provider to override the default
+ result = if resource_hash.key? :title
+ new(title: resource_hash[:title])
+ else
+ new(title: resource_hash[type_definition.namevars.first])
+ end
result.cache_current_state(resource_hash)
result
end
end
define_method(:refresh_current_state) do
- @rapi_current_state = if type_definition.feature?('simple_get_filter')
- my_provider.get(context, [title]).first
- else
- my_provider.get(context).find { |h| namevar_match?(h) }
- end
+ @rsapi_current_state = if type_definition.feature?('simple_get_filter')
+ my_provider.get(context, [title]).find { |h| namevar_match?(h) }
+ else
+ my_provider.get(context).find { |h| namevar_match?(h) }
+ end
- if @rapi_current_state
- type_definition.check_schema(@rapi_current_state)
- strict_check(@rapi_current_state) if type_definition.feature?('canonicalize')
+ if @rsapi_current_state
+ type_definition.check_schema(@rsapi_current_state)
+ strict_check(@rsapi_current_state) if type_definition.feature?('canonicalize')
else
- @rapi_current_state = { title: title }
- @rapi_current_state[:ensure] = :absent if type_definition.ensurable?
+ @rsapi_current_state = { title: title }
+ @rsapi_current_state[:ensure] = :absent if type_definition.ensurable?
end
end
# Use this to set the current state from the `instances` method
def cache_current_state(resource_hash)
- @rapi_current_state = resource_hash
- strict_check(@rapi_current_state) if type_definition.feature?('canonicalize')
+ @rsapi_current_state = resource_hash
+ strict_check(@rsapi_current_state) if type_definition.feature?('canonicalize')
end
define_method(:retrieve) do
- refresh_current_state unless @rapi_current_state
+ refresh_current_state unless @rsapi_current_state
- Puppet.debug("Current State: #{@rapi_current_state.inspect}")
+ Puppet.debug("Current State: #{@rsapi_current_state.inspect}")
- result = Puppet::Resource.new(self.class, title, parameters: @rapi_current_state)
+ result = Puppet::Resource.new(self.class, title, parameters: @rsapi_current_state)
# puppet needs ensure to be a symbol
result[:ensure] = result[:ensure].to_sym if type_definition.ensurable? && result[:ensure].is_a?(String)
raise_missing_attrs
@@ -358,38 +384,38 @@
# skip puppet's injected metaparams
actual_params = @parameters.select { |k, _v| type_definition.attributes.key? k }
target_state = Hash[actual_params.map { |k, v| [k, v.rs_value] }]
target_state = my_provider.canonicalize(context, [target_state]).first if type_definition.feature?('canonicalize')
- retrieve unless @rapi_current_state
+ retrieve unless @rsapi_current_state
- return if @rapi_current_state == target_state
+ return if @rsapi_current_state == target_state
Puppet.debug("Target State: #{target_state.inspect}")
# enforce init_only attributes
- if Puppet.settings[:strict] != :off && @rapi_current_state && (@rapi_current_state[:ensure] == 'present' && target_state[:ensure] == 'present')
+ if Puppet.settings[:strict] != :off && @rsapi_current_state && (@rsapi_current_state[:ensure] == 'present' && target_state[:ensure] == 'present')
target_state.each do |name, value|
- next unless definition[:attributes][name][:behaviour] == :init_only && value != @rapi_current_state[name]
- message = "Attempting to change `#{name}` init_only attribute value from `#{@rapi_current_state[name]}` to `#{value}`"
+ next unless definition[:attributes][name][:behaviour] == :init_only && value != @rsapi_current_state[name]
+ message = "Attempting to change `#{name}` init_only attribute value from `#{@rsapi_current_state[name]}` to `#{value}`"
case Puppet.settings[:strict]
when :warning
Puppet.warning(message)
when :error
raise Puppet::ResourceError, message
end
end
end
if type_definition.feature?('supports_noop')
- my_provider.set(context, { title => { is: @rapi_current_state, should: target_state } }, noop: noop?)
+ my_provider.set(context, { title => { is: @rsapi_current_state, should: target_state } }, noop: noop?)
else
- my_provider.set(context, title => { is: @rapi_current_state, should: target_state }) unless noop?
+ my_provider.set(context, title => { is: @rsapi_current_state, should: target_state }) unless noop?
end
raise 'Execution encountered an error' if context.failed?
# remember that we have successfully reached our desired state
- @rapi_current_state = target_state
+ @rsapi_current_state = target_state
end
define_method(:raise_missing_attrs) do
error_msg = "The following mandatory attributes were not provided:\n * " + @missing_attrs.join(", \n * ")
raise Puppet::ResourceError, error_msg if @missing_attrs.any? && (value(:ensure) != :absent && !value(:ensure).nil?)