@@ -81,14 +81,10 @@ def resolve_deferred_values!
8181 Puppet . notice ( 'DSC PROVIDER → Resolving deferred values in properties' )
8282
8383 begin
84- # Get the facts that are available on the agent
85- facts = Puppet . lookup ( :facts ) { nil }
86-
87- # Create a minimal evaluation context for deferred resolution
88- # This approach uses Puppet's built-in deferred resolution mechanism
89- resolved_properties = resolve_deferred_recursively ( current_properties , facts )
84+ # Resolve deferred values directly using the properties hash
85+ resolved_properties = manually_resolve_deferred_values ( current_properties )
9086
91- # Update the parameter value with the resolved version
87+ # Update the resource with resolved properties
9288 resource . parameters [ :properties ] . value = resolved_properties
9389
9490 # Verify resolution worked
@@ -99,70 +95,66 @@ def resolve_deferred_values!
9995 end
10096 rescue => e
10197 Puppet . warning ( "DSC PROVIDER → Error resolving deferred values: #{ e . class } : #{ e . message } " )
98+ Puppet . debug ( "DSC PROVIDER → Error backtrace: #{ e . backtrace . join ( "\n " ) } " )
10299 # Continue with unresolved values - they will be stringified but at least won't crash
103100 end
104101 end
105102
106- # Check if a value contains any deferred values (recursively)
107- def contains_deferred_values? ( value )
103+ # Recursively resolve deferred values in a data structure
104+ def manually_resolve_deferred_values ( value )
108105 case value
109106 when Hash
110- value . any? { |k , v | contains_deferred_values? ( k ) || contains_deferred_values? ( v ) }
111- when Array
112- value . any? { |v | contains_deferred_values? ( v ) }
113- else
114- # Check if this is a Deferred object
115- value && value . class . name . include? ( 'Deferred' )
116- end
117- end
118-
119- # Recursively resolve deferred values using Puppet's deferred function mechanism
120- def resolve_deferred_recursively ( value , facts )
121- case value
122- when Hash
123- result = { }
107+ resolved_hash = { }
124108 value . each do |k , v |
125- result [ resolve_deferred_recursively ( k , facts ) ] = resolve_deferred_recursively ( v , facts )
109+ resolved_key = manually_resolve_deferred_values ( k )
110+ resolved_value = manually_resolve_deferred_values ( v )
111+ resolved_hash [ resolved_key ] = resolved_value
126112 end
127- result
113+ resolved_hash
128114 when Array
129- value . map { |v | resolve_deferred_recursively ( v , facts ) }
115+ value . map { |v | manually_resolve_deferred_values ( v ) }
130116 else
131- # If this is a Deferred object, resolve it
132- if value && value . class . name . include? ( 'Deferred' )
133- resolve_single_deferred ( value , facts )
134- else
135- value
117+ # Handle different types of deferred objects
118+ if value . is_a? ( Puppet ::Pops ::Evaluator ::DeferredValue )
119+ # DeferredValue objects have a @proc instance variable we can call
120+ proc = value . instance_variable_get ( :@proc )
121+ return proc . call if proc && proc . respond_to? ( :call )
122+
123+ Puppet . debug ( 'DSC PROVIDER → DeferredValue has no callable proc' )
124+ return value . to_s
125+
126+ elsif value && value . class . name . include? ( 'Deferred' )
127+ # For other Deferred types, try standard resolution
128+ if value . respond_to? ( :name )
129+ begin
130+ return Puppet ::Pops ::Evaluator ::DeferredResolver . resolve ( value . name , nil , { } )
131+ rescue => e
132+ Puppet . debug ( "DSC PROVIDER → Failed to resolve Deferred object: #{ e . message } " )
133+ return value . to_s
134+ end
135+ else
136+ Puppet . debug ( 'DSC PROVIDER → Deferred object has no name method' )
137+ return value . to_s
138+ end
136139 end
140+
141+ # Return the value unchanged if it's not deferred
142+ value
137143 end
138144 end
139145
140- # Resolve a single Deferred object
141- def resolve_single_deferred ( deferred_value , _facts )
142- # For Deferred objects, we need to call the actual function with the parameters
143- # This mimics what Puppet does during normal deferred resolution
144-
145- function_name = deferred_value . name
146- arguments = deferred_value . arguments
147-
148- # Call the function with the provided arguments
149- # This uses Puppet's function loading mechanism
150- loaders = Puppet . lookup ( :loaders )
151- function_loader = loaders . private_environment_loader || loaders . static_loader
152- function = function_loader . load ( :function , function_name )
153-
154- if function
155- # Execute the function with the arguments
156- result = function . call ( { } , *arguments )
157- Puppet . debug ( "DSC PROVIDER → Resolved Deferred('#{ function_name } ', #{ arguments . inspect } ) → #{ result . inspect } " )
158- result
146+ # Check if a value contains any deferred values (recursively)
147+ def contains_deferred_values? ( value )
148+ case value
149+ when Hash
150+ value . any? { |k , v | contains_deferred_values? ( k ) || contains_deferred_values? ( v ) }
151+ when Array
152+ value . any? { |v | contains_deferred_values? ( v ) }
159153 else
160- Puppet . warning ( "DSC PROVIDER → Could not load function '#{ function_name } ' for deferred resolution" )
161- deferred_value
154+ # Check if this is a Deferred object or DeferredValue
155+ value && ( value . class . name . include? ( 'Deferred' ) ||
156+ value . is_a? ( Puppet ::Pops ::Evaluator ::DeferredValue ) )
162157 end
163- rescue => e
164- Puppet . warning ( "DSC PROVIDER → Error resolving Deferred('#{ function_name } '): #{ e . message } " )
165- deferred_value
166158 end
167159
168160 # ---------------------------
0 commit comments