class Puppet::Pops::Evaluator::DeferredResolver

Utility class to help resolve instances of Puppet::Pops::Types::PDeferredType::Deferred

Constants

DIG
DOLLAR

Public Class Methods

new(compiler) click to toggle source
   # File lib/puppet/pops/evaluator/deferred_resolver.rb
56 def initialize(compiler)
57   @compiler = compiler
58   # Always resolve in top scope
59   @scope = @compiler.topscope
60   @deferred_class = Puppet::Pops::Types::TypeFactory.deferred.implementation_class
61 end
resolve(value, compiler) click to toggle source

Resolves a value such that a direct Deferred, or any nested Deferred values are resolved and used instead of the deferred value. A direct Deferred value, or nested deferred values inside of Array, Hash or Sensitive values are resolved and replaced inside of freshly created containers.

The resolution takes place in the topscope of the given compiler. Variable values are supposed to already have been set.

@param value [Object] the (possibly nested) value to resolve @param compiler [Puppet::Parser::ScriptCompiler, Puppet::Parser::Compiler] the compiler in effect @return [Object] the resolved value (a new Array, Hash, or Sensitive if needed), with all deferred values resolved

   # File lib/puppet/pops/evaluator/deferred_resolver.rb
51 def self.resolve(value, compiler)
52   resolver = new(compiler)
53   resolver.resolve(value)
54 end
resolve_and_replace(facts, catalog, environment = catalog.environment_instance) click to toggle source

Resolves and replaces all Deferred values in a catalog's resource attributes found as direct values or nested inside Array, Hash or Sensitive values. Deferred values inside of custom Object instances are not resolved as this is expected to be done by such objects.

@param facts [Puppet::Node::Facts] the facts object for the node @param catalog [Puppet::Resource::Catalog] the catalog where all deferred values should be replaced @param environment [Puppet::Node::Environment] the environment whose anonymous module methods

are to be mixed into the scope

@return [nil] does not return anything - the catalog is modified as a side effect

   # File lib/puppet/pops/evaluator/deferred_resolver.rb
23 def self.resolve_and_replace(facts, catalog, environment = catalog.environment_instance)
24   compiler = Puppet::Parser::ScriptCompiler.new(environment, catalog.name, true)
25   resolver = new(compiler)
26   resolver.set_facts_variable(facts)
27   # TODO:
28   #    # When scripting the trusted data are always local, but set them anyway
29   #    @scope.set_trusted(node.trusted_data)
30   #
31   #    # Server facts are always about the local node's version etc.
32   #    @scope.set_server_facts(node.server_facts)
33 
34   resolver.resolve_futures(catalog)
35   nil
36 end

Public Instance Methods

resolve(x) click to toggle source
    # File lib/puppet/pops/evaluator/deferred_resolver.rb
 89 def resolve(x)
 90   if x.class == @deferred_class
 91     resolve_future(x)
 92   elsif x.is_a?(Array)
 93     x.map {|v| resolve(v) }
 94   elsif x.is_a?(Hash)
 95     result = {}
 96     x.each_pair {|k,v| result[k] = resolve(v) }
 97     result
 98   elsif x.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
 99     # rewrap in a new Sensitive after resolving any nested deferred values
100     Puppet::Pops::Types::PSensitiveType::Sensitive.new(resolve(x.unwrap))
101   elsif x.is_a?(Puppet::Pops::Types::PBinaryType::Binary)
102     # use the ASCII-8BIT string that it wraps
103     x.binary_buffer
104   else
105     x
106   end
107 end
resolve_future(f) click to toggle source
    # File lib/puppet/pops/evaluator/deferred_resolver.rb
109 def resolve_future(f)
110   # If any of the arguments to a future is a future it needs to be resolved first
111   func_name = f.name
112   mapped_arguments = map_arguments(f.arguments)
113   # if name starts with $ then this is a call to dig
114   if func_name[0] == DOLLAR
115     var_name = func_name[1..-1]
116     func_name = DIG
117     mapped_arguments.insert(0, @scope[var_name])
118   end
119 
120   # call the function (name in deferred, or 'dig' for a variable)
121   @scope.call_function(func_name, mapped_arguments)
122 end
resolve_futures(catalog) click to toggle source
   # File lib/puppet/pops/evaluator/deferred_resolver.rb
69 def resolve_futures(catalog)
70   catalog.resources.each do |r|
71     overrides = {}
72     r.parameters.each_pair do |k, v|
73       resolved = resolve(v)
74       # If the value is instance of Sensitive - assign the unwrapped value
75       # and mark it as sensitive if not already marked
76       #
77       if resolved.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
78         resolved = resolved.unwrap
79         unless r.sensitive_parameters.include?(k.to_sym)
80           r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze
81         end
82       end
83       overrides[ k ] = resolved
84     end
85     r.parameters.merge!(overrides) unless overrides.empty?
86   end
87 end
set_facts_variable(facts) click to toggle source

@param facts [Puppet::Node::Facts] the facts to set in $facts in the compiler's topscope

   # File lib/puppet/pops/evaluator/deferred_resolver.rb
65 def set_facts_variable(facts)
66   @scope.set_facts(facts.nil? ? {} : facts.values)
67 end

Private Instance Methods

map_arguments(args) click to toggle source
    # File lib/puppet/pops/evaluator/deferred_resolver.rb
124 def map_arguments(args)
125   return [] if args.nil?
126   args.map {|v| resolve(v) }
127 end