diff --git a/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb b/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb index b5861dd6..0f7e806e 100644 --- a/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb +++ b/lib/puppet/provider/dsc_base_provider/dsc_base_provider.rb @@ -351,7 +351,7 @@ def insync?(context, name, _property_name, _is_hash, should_hash) # @param context [Object] the Puppet runtime context to operate in and send feedback to # @param name_hash [Hash] the hash of namevars to be passed as properties to `Invoke-DscResource` # @return [Hash] returns a hash representing the DSC resource munged to the representation the Puppet Type expects - def invoke_get_method(context, name_hash) + def invoke_get_method(context, name_hash) # rubocop:disable Metrics/AbcSize context.debug("retrieving #{name_hash.inspect}") query_props = name_hash.select { |k, v| mandatory_get_attributes(context).include?(k) || (k == :dsc_psdscrunascredential && !v.nil?) } @@ -394,6 +394,8 @@ def invoke_get_method(context, name_hash) # If a resource is found, it's present, so refill this Puppet-only key data[:name] = name_hash[:name] + data = stringify_nil_attributes(context, data) + # Have to check for this to avoid a weird canonicalization warning # The Resource API calls canonicalize against the current state which # will lead to dsc_ensure being set to absent in the name_hash even if @@ -663,6 +665,20 @@ def mandatory_set_attributes(context) context.type.attributes.select { |_attribute, properties| properties[:mandatory_for_set] }.keys end + # Parses the DSC resource type definition to retrieve the names of any attributes which are specifed as required strings + # This is used to ensure that any nil values are converted to empty strings to match puppets expecetd value + # @param context [Object] the Puppet runtime context to operate in and send feedback to + # @param data [Hash] the hash of properties returned from the DSC resource + # @return [Hash] returns a data hash with any nil values converted to empty strings + def stringify_nil_attributes(context, data) + nil_strings = data.select { |_name, value| value.nil? }.keys + string_attrs = context.type.attributes.select { |_name, properties| properties[:type] == 'String' }.keys + string_attrs.each do |attribute| + data[attribute] = '' if nil_strings.include?(attribute) + end + data + end + # Parses the DSC resource type definition to retrieve the names of any attributes which are specified as namevars # # @param context [Object] the Puppet runtime context to operate in and send feedback to