class Puppet::Application::Lookup

Constants

DEEP_MERGE_OPTIONS
RUN_HELP

Public Instance Methods

app_defaults() click to toggle source
Calls superclass method Puppet::Application#app_defaults
   # File lib/puppet/application/lookup.rb
64 def app_defaults
65   super.merge({
66     :facts_terminus => 'yaml'
67   })
68 end
generate_scope() { |topscope| ... } click to toggle source
    # File lib/puppet/application/lookup.rb
333 def generate_scope
334   if options[:node]
335     node = options[:node]
336   else
337     node = Puppet[:node_name_value]
338 
339     # If we want to lookup the node we are currently on
340     # we must returning these settings to their default values
341     Puppet.settings[:facts_terminus] = 'facter'
342   end
343 
344   unless node.is_a?(Puppet::Node) # to allow unit tests to pass a node instance
345     ni = Puppet::Node.indirection
346     tc = ni.terminus_class
347     if tc == :plain || options[:compile]
348       node = ni.find(node)
349     else
350       ni.terminus_class = :plain
351       node = ni.find(node)
352       ni.terminus_class = tc
353     end
354   end
355 
356   fact_file = options[:fact_file]
357 
358   if fact_file
359     if fact_file.end_with?("json")
360       given_facts = Puppet::Util::Json.load(Puppet::FileSystem.read(fact_file, :encoding => 'utf-8'))
361     else
362       given_facts = Puppet::Util::Yaml.safe_load_file(fact_file)
363     end
364 
365     unless given_facts.instance_of?(Hash)
366       raise _("Incorrect formatted data in %{fact_file} given via the --facts flag") % { fact_file: fact_file }
367     end
368     node.add_extra_facts(given_facts)
369   end
370 
371   Puppet[:code] = 'undef' unless options[:compile]
372   compiler = Puppet::Parser::Compiler.new(node)
373   if options[:node]
374     Puppet::Util.skip_external_facts do
375       compiler.compile { |catalog| yield(compiler.topscope); catalog }
376     end
377   else
378     compiler.compile { |catalog| yield(compiler.topscope); catalog }
379   end
380 end
help() click to toggle source
    # File lib/puppet/application/lookup.rb
108   def help
109     <<-HELP
110 
111 puppet-lookup(8) -- #{summary}
112 ========
113 
114 SYNOPSIS
115 --------
116 Does Hiera lookups from the command line.
117 
118 Since this command needs access to your Hiera data, make sure to run it on a
119 node that has a copy of that data. This usually means logging into a Puppet
120 Server node and running 'puppet lookup' with sudo.
121 
122 The most common version of this command is:
123 
124 'puppet lookup <KEY> --node <NAME> --environment <ENV> --explain'
125 
126 USAGE
127 -----
128 puppet lookup [--help] [--type <TYPESTRING>] [--merge first|unique|hash|deep]
129   [--knock-out-prefix <PREFIX-STRING>] [--sort-merged-arrays]
130   [--merge-hash-arrays] [--explain] [--environment <ENV>]
131   [--default <VALUE>] [--node <NODE-NAME>] [--facts <FILE>]
132   [--compile]
133   [--render-as s|json|yaml|binary|msgpack] <keys>
134 
135 DESCRIPTION
136 -----------
137 The lookup command is a CLI for Puppet's 'lookup()' function. It searches your
138 Hiera data and returns a value for the requested lookup key, so you can test and
139 explore your data. It is a modern replacement for the 'hiera' command.
140 
141 Hiera usually relies on a node's facts to locate the relevant data sources. By
142 default, 'puppet lookup' uses facts from the node you run the command on, but
143 you can get data for any other node with the '--node <NAME>' option. If
144 possible, the lookup command will use the requested node's real stored facts
145 from PuppetDB; if PuppetDB isn't configured or you want to provide arbitrary
146 fact values, you can pass alternate facts as a JSON or YAML file with '--facts
147 <FILE>'.
148 
149 If you're debugging your Hiera data and want to see where values are coming
150 from, use the '--explain' option.
151 
152 If '--explain' isn't specified, lookup exits with 0 if a value was found and 1
153 otherwise. With '--explain', lookup always exits with 0 unless there is a major
154 error.
155 
156 You can provide multiple lookup keys to this command, but it only returns a
157 value for the first found key, omitting the rest.
158 
159 For more details about how Hiera works, see the Hiera documentation:
160 https://puppet.com/docs/puppet/latest/hiera_intro.html
161 
162 OPTIONS
163 -------
164 
165 * --help:
166   Print this help message.
167 
168 * --explain
169   Explain the details of how the lookup was performed and where the final value
170   came from (or the reason no value was found).
171 
172 * --node <NODE-NAME>
173   Specify which node to look up data for; defaults to the node where the command
174   is run. Since Hiera's purpose is to provide different values for different
175   nodes (usually based on their facts), you'll usually want to use some specific
176   node's facts to explore your data. If the node where you're running this
177   command is configured to talk to PuppetDB, the command will use the requested
178   node's most recent facts. Otherwise, you can override facts with the '--facts'
179   option.
180 
181 * --facts <FILE>
182   Specify a .json or .yaml file of key => value mappings to override the facts
183   for this lookup. Any facts not specified in this file maintain their
184   original value.
185 
186 * --environment <ENV>
187   Like with most Puppet commands, you can specify an environment on the command
188   line. This is important for lookup because different environments can have
189   different Hiera data.
190 
191 * --merge first|unique|hash|deep:
192   Specify the merge behavior, overriding any merge behavior from the data's
193   lookup_options. 'first' returns the first value found. 'unique' appends
194   everything to a merged, deduplicated array. 'hash' performs a simple hash
195   merge by overwriting keys of lower lookup priority. 'deep' performs a deep
196   merge on values of Array and Hash type. There are additional options that can
197   be used with 'deep'.
198 
199 * --knock-out-prefix <PREFIX-STRING>
200   Can be used with the 'deep' merge strategy. Specifies a prefix to indicate a
201   value should be removed from the final result.
202 
203 * --sort-merged-arrays
204   Can be used with the 'deep' merge strategy. When this flag is used, all
205   merged arrays are sorted.
206 
207 * --merge-hash-arrays
208   Can be used with the 'deep' merge strategy. When this flag is used, hashes
209   WITHIN arrays are deep-merged with their counterparts by position.
210 
211 * --explain-options
212   Explain whether a lookup_options hash affects this lookup, and how that hash
213   was assembled. (lookup_options is how Hiera configures merge behavior in data.)
214 
215 * --default <VALUE>
216   A value to return if Hiera can't find a value in data. For emulating calls to
217   the 'lookup()' function that include a default.
218 
219 * --type <TYPESTRING>:
220   Assert that the value has the specified type. For emulating calls to the
221   'lookup()' function that include a data type.
222 
223 * --compile
224   Perform a full catalog compilation prior to the lookup. If your hierarchy and
225   data only use the $facts, $trusted, and $server_facts variables, you don't
226   need this option; however, if your Hiera configuration uses arbitrary
227   variables set by a Puppet manifest, you might need this option to get accurate
228   data. No catalog compilation takes place unless this flag is given.
229 
230 * --render-as s|json|yaml|binary|msgpack
231   Specify the output format of the results; "s" means plain text. The default
232   when producing a value is yaml and the default when producing an explanation
233   is s.
234 
235 EXAMPLE
236 -------
237   To look up 'key_name' using the Puppet Server node's facts:
238   $ puppet lookup key_name
239 
240   To look up 'key_name' with agent.local's facts:
241   $ puppet lookup --node agent.local key_name
242 
243   To get the first value found for 'key_name_one' and 'key_name_two'
244   with agent.local's facts while merging values and knocking out
245   the prefix 'foo' while merging:
246   $ puppet lookup --node agent.local --merge deep --knock-out-prefix foo key_name_one key_name_two
247 
248   To lookup 'key_name' with agent.local's facts, and return a default value of
249   'bar' if nothing was found:
250   $ puppet lookup --node agent.local --default bar key_name
251 
252   To see an explanation of how the value for 'key_name' would be found, using
253   agent.local's facts:
254   $ puppet lookup --node agent.local --explain key_name
255 
256 COPYRIGHT
257 ---------
258 Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
259 
260 
261     HELP
262   end
main() click to toggle source
    # File lib/puppet/application/lookup.rb
264 def main
265   keys = command_line.args
266 
267   #unless options[:node]
268   #  raise "No node was given via the '--node' flag for the scope of the lookup.\n#{RUN_HELP}"
269   #end
270 
271   if (options[:sort_merged_arrays] || options[:merge_hash_arrays] || options[:prefix]) && options[:merge] != 'deep'
272     raise _("The options %{deep_merge_opts} are only available with '--merge deep'\n%{run_help}") % { deep_merge_opts: DEEP_MERGE_OPTIONS, run_help: RUN_HELP }
273   end
274 
275   use_default_value = !options[:default_value].nil?
276   merge_options = nil
277 
278   merge = options[:merge]
279   unless merge.nil?
280     strategies = Puppet::Pops::MergeStrategy.strategy_keys
281     unless strategies.include?(merge.to_sym)
282       strategies = strategies.map {|k| "'#{k}'"}
283       raise _("The --merge option only accepts %{strategies}, or %{last_strategy}\n%{run_help}") % { strategies: strategies[0...-1].join(', '), last_strategy: strategies.last, run_help: RUN_HELP }
284     end
285 
286     if merge == 'deep'
287       merge_options = {'strategy' => 'deep',
288         'sort_merged_arrays' => !options[:sort_merged_arrays].nil?,
289         'merge_hash_arrays' => !options[:merge_hash_arrays].nil?}
290 
291       if options[:prefix]
292         merge_options['knockout_prefix'] = options[:prefix]
293       end
294 
295     else
296       merge_options = {'strategy' => merge}
297     end
298   end
299 
300   explain_data = !!options[:explain]
301   explain_options = !!options[:explain_options]
302   only_explain_options = explain_options && !explain_data
303   if keys.empty?
304     if only_explain_options
305       # Explain lookup_options for lookup of an unqualified value.
306       keys = Puppet::Pops::Lookup::GLOBAL
307     else
308       raise _('No keys were given to lookup.')
309     end
310   end
311   explain = explain_data || explain_options
312 
313   # Format defaults to text (:s) when producing an explanation and :yaml when producing the value
314   format = options[:render_as] || (explain ? :s : :yaml)
315   renderer = Puppet::Network::FormatHandler.format(format)
316   raise _("Unknown rendering format '%{format}'") % { format: format } if renderer.nil?
317 
318   generate_scope do |scope|
319     lookup_invocation = Puppet::Pops::Lookup::Invocation.new(scope, {}, {}, explain ? Puppet::Pops::Lookup::Explainer.new(explain_options, only_explain_options) : nil)
320     begin
321       type = options.include?(:type) ? Puppet::Pops::Types::TypeParser.singleton.parse(options[:type], scope) : nil
322       result = Puppet::Pops::Lookup.lookup(keys, type, options[:default_value], use_default_value, merge_options, lookup_invocation)
323       puts renderer.render(result) unless explain
324     rescue Puppet::DataBinding::LookupError => e
325       lookup_invocation.report_text { e.message }
326       exit(1) unless explain
327     end
328     puts format == :s ? lookup_invocation.explainer.explain : renderer.render(lookup_invocation.explainer.to_hash) if explain
329   end
330   exit(0)
331 end
setup() click to toggle source
    # File lib/puppet/application/lookup.rb
 88 def setup
 89   setup_logs
 90 
 91   exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
 92 
 93   if options[:node]
 94     Puppet::Util.skip_external_facts do
 95       Puppet.settings.use :main, :server, :ssl, :metrics
 96     end
 97   else
 98     Puppet.settings.use :main, :server, :ssl, :metrics
 99   end
100 
101   setup_terminuses
102 end
setup_logs() click to toggle source
   # File lib/puppet/application/lookup.rb
70 def setup_logs
71   # This sets up logging based on --debug or --verbose if they are set in `options`
72   set_log_level
73 
74   # This uses console for everything that is not a compilation
75   Puppet::Util::Log.newdestination(:console)
76 end
setup_terminuses() click to toggle source
   # File lib/puppet/application/lookup.rb
78 def setup_terminuses
79   require_relative '../../puppet/file_serving/content'
80   require_relative '../../puppet/file_serving/metadata'
81 
82   Puppet::FileServing::Content.indirection.terminus_class = :file_server
83   Puppet::FileServing::Metadata.indirection.terminus_class = :file_server
84 
85   Puppet::FileBucket::File.indirection.terminus_class = :file
86 end
summary() click to toggle source
    # File lib/puppet/application/lookup.rb
104 def summary
105   _("Interactive Hiera lookup")
106 end