class Puppet::HTTP::Service::Compiler

The Compiler service is used to submit and retrieve data from the puppetserver.

@api public

Constants

API

@return [String] Default API for the Compiler service

Public Class Methods

new(client, session, server, port) click to toggle source

Use `Puppet::HTTP::Session.route_to(:puppet)` to create or get an instance of this class.

@param [Puppet::HTTP::Client] client @param [Puppet::HTTP::Session] session @param [String] server (`Puppet`) If an explicit server is given,

create a service using that server. If server is nil, the default value
is used to create the service.

@param [Integer] port (`Puppet`) If an explicit port is given, create

a service using that port. If port is nil, the default value is used to
create the service.
Calls superclass method Puppet::HTTP::Service::new
   # File lib/puppet/http/service/compiler.rb
20 def initialize(client, session, server, port)
21   url = build_url(API, server || Puppet[:server], port || Puppet[:serverport])
22   super(client, session, url)
23 end

Public Instance Methods

get_facts(name, environment:) click to toggle source

@api private

Submit a GET request to retrieve the facts for the named node

@param [String] name Name of the node to retrieve facts for @param [String] environment Name of the environment we are operating in

@return [Array<Puppet::HTTP::Response, Puppet::Node::Facts>] An array

containing the request response and the deserialized facts for the
specified node

@api public

    # File lib/puppet/http/service/compiler.rb
209 def get_facts(name, environment:)
210   headers = add_puppet_headers('Accept' => get_mime_types(Puppet::Node::Facts).join(', '))
211 
212   response = @client.get(
213     with_base_url("/facts/#{name}"),
214     headers: headers,
215     params: { environment: environment }
216   )
217 
218   process_response(response)
219 
220   [response, deserialize(response, Puppet::Node::Facts)]
221 end
get_filebucket_file(path, environment:, bucket_path: nil, diff_with: nil, list_all: nil, fromdate: nil, todate: nil) click to toggle source

Submit a GET request to retrieve a file stored with filebucket.

@param [String] path The request path, formatted by `Puppet::FileBucket::Dipper` @param [String] environment Name of the environment we are operating in.

This should not impact filebucket at all, but is included to be consistent
with legacy code.

@param [String] bucket_path @param [String] diff_with a checksum to diff against if we are comparing

files that are both stored in the bucket

@param [String] list_all @param [String] fromdate @param [String] todate

@return [Array<Puppet::HTTP::Response, Puppet::FileBucket::File>] An array

containing the request response and the deserialized file returned from
the server.

@api public

    # File lib/puppet/http/service/compiler.rb
270 def get_filebucket_file(path, environment:, bucket_path: nil, diff_with: nil, list_all: nil, fromdate: nil, todate: nil)
271   headers = add_puppet_headers('Accept' => 'application/octet-stream')
272 
273   response = @client.get(
274     with_base_url("/file_bucket_file/#{path}"),
275     headers: headers,
276     params: {
277       environment: environment,
278       bucket_path: bucket_path,
279       diff_with: diff_with,
280       list_all: list_all,
281       fromdate: fromdate,
282       todate: todate
283     }
284   )
285 
286   process_response(response)
287 
288   [response, deserialize(response, Puppet::FileBucket::File)]
289 end
get_node(name, environment:, configured_environment: nil, transaction_uuid: nil) click to toggle source

Submit a GET request to retrieve a node from the server.

@param [String] name The name of the node being requested @param [String] environment The name of the environment we are operating in @param [String] configured_environment Optional, the name of the configured

environment. If unset, `environment` is used.

@param [String] transaction_uuid An agent generated transaction uuid, used

for connecting catalogs and reports.

@return [Array<Puppet::HTTP::Response, Puppet::Node>] An array containing

the request response and the deserialized requested node

@api public

   # File lib/puppet/http/service/compiler.rb
38 def get_node(name, environment:, configured_environment: nil, transaction_uuid: nil)
39   headers = add_puppet_headers('Accept' => get_mime_types(Puppet::Node).join(', '))
40 
41   response = @client.get(
42     with_base_url("/node/#{name}"),
43     headers: headers,
44     params: {
45       environment: environment,
46       configured_environment: configured_environment || environment,
47       transaction_uuid: transaction_uuid,
48     }
49   )
50 
51   process_response(response)
52 
53   [response, deserialize(response, Puppet::Node)]
54 end
head_filebucket_file(path, environment:, bucket_path: nil) click to toggle source

Submit a HEAD request to check the status of a file stored with filebucket.

@param [String] path The request path, formatted by `Puppet::FileBucket::Dipper` @param [String] environment Name of the environment we are operating in.

This should not impact filebucket at all, but is included to be consistent
with legacy code.

@param [String] bucket_path

@return [Puppet::HTTP::Response] The request response

@api public

    # File lib/puppet/http/service/compiler.rb
333 def head_filebucket_file(path, environment:, bucket_path: nil)
334   headers = add_puppet_headers('Accept' => 'application/octet-stream')
335 
336   response = @client.head(
337     with_base_url("/file_bucket_file/#{path}"),
338     headers: headers,
339     params: {
340       environment: environment,
341       bucket_path: bucket_path
342     }
343   )
344 
345   process_response(response)
346 
347   response
348 end
post_catalog(name, facts:, environment:, configured_environment: nil, check_environment: false, transaction_uuid: nil, job_uuid: nil, static_catalog: true, checksum_type: Puppet[:supported_checksum_types]) click to toggle source

Submit a POST request to submit a catalog to the server.

@param [String] name The name of the catalog to be submitted @param [Puppet::Node::Facts] facts Facts for this catalog @param [String] environment The name of the environment we are operating in @param [String] configured_environment Optional, the name of the configured

environment. If unset, `environment` is used.

@param [Boolean] check_environment If true, request that the server check if

our `environment` matches the server-specified environment. If they do not
match, then the server may return an empty catalog in the server-specified
environment.

@param [String] transaction_uuid An agent generated transaction uuid, used

for connecting catalogs and reports.

@param [String] job_uuid A unique job identifier defined when the orchestrator

starts a puppet run via pxp-agent. This is used to correlate catalogs and
reports with the orchestrator job.

@param [Boolean] static_catalog Indicates if the file metadata(s) are inlined

in the catalog. This informs the agent if it needs to make a second request
to retrieve metadata in addition to the initial catalog request.

@param [Array<String>] checksum_type An array of accepted checksum types.

@return [Array<Puppet::HTTP::Response, Puppet::Resource::Catalog>] An array

containing the request response and the deserialized catalog returned by
the server

@api public

    # File lib/puppet/http/service/compiler.rb
 82 def post_catalog(name, facts:, environment:, configured_environment: nil, check_environment: false, transaction_uuid: nil, job_uuid: nil, static_catalog: true, checksum_type: Puppet[:supported_checksum_types])
 83   if Puppet[:preferred_serialization_format] == "pson"
 84     formatter = Puppet::Network::FormatHandler.format_for(:pson)
 85     # must use 'pson' instead of 'text/pson'
 86     facts_format = 'pson'
 87   else
 88     formatter = Puppet::Network::FormatHandler.format_for(:json)
 89     facts_format = formatter.mime
 90   end
 91 
 92   facts_as_string = serialize(formatter, facts)
 93 
 94   # query parameters are sent in the POST request body
 95   body = {
 96     facts_format: facts_format,
 97     facts: Puppet::Util.uri_query_encode(facts_as_string),
 98     environment: environment,
 99     configured_environment: configured_environment || environment,
100     check_environment: !!check_environment,
101     transaction_uuid: transaction_uuid,
102     job_uuid: job_uuid,
103     static_catalog: static_catalog,
104     checksum_type: checksum_type.join('.')
105   }.map do |key, value|
106     "#{key}=#{Puppet::Util.uri_query_encode(value.to_s)}"
107   end.join("&")
108 
109   headers = add_puppet_headers(
110     'Accept' => get_mime_types(Puppet::Resource::Catalog).join(', '),
111     'Content-Type' => 'application/x-www-form-urlencoded'
112   )
113 
114   response = @client.post(
115     with_base_url("/catalog/#{name}"),
116     body,
117     headers: headers,
118     # for legacy reasons we always send environment as a query parameter too
119     params: { environment: environment },
120   )
121 
122   process_response(response)
123 
124   [response, deserialize(response, Puppet::Resource::Catalog)]
125 end
post_catalog4(certname, persistence:, environment:, facts: nil, trusted_facts: nil, transaction_uuid: nil, job_id: nil, options: nil) click to toggle source

@api private

Submit a POST request to request a catalog to the server using v4 endpoint

@param [String] certname The name of the node for which to compile the catalog. @param [Hash] persistent A hash containing two required keys, facts and catalog,

which when set to true will cause the facts and reports to be stored in
PuppetDB, or discarded if set to false.

@param [String] environment The name of the environment for which to compile the catalog. @param [Hash] facts A hash with a required values key, containing a hash of all the

facts for the node. If not provided, Puppet will attempt to fetch facts for the node
from PuppetDB.

@param [Hash] trusted_facts A hash with a required values key containing a hash of

the trusted facts for a node

@param [String] transaction_uuid The id for tracking the catalog compilation and

report submission.

@param [String] job_id The id of the orchestrator job that triggered this run. @param [Hash] options A hash of options beyond direct input to catalogs. Options:

- prefer_requested_environment Whether to always override a node's classified 
  environment with the one supplied in the request. If this is true and no environment
  is supplied, fall back to the classified environment, or finally, 'production'.
- capture_logs Whether to return the errors and warnings that occurred during
  compilation alongside the catalog in the response body.
- log_level The logging level to use during the compile when capture_logs is true.
  Options are 'err', 'warning', 'info', and 'debug'.

@return [Array<Puppet::HTTP::Response, Puppet::Resource::Catalog, Array<String>>] An array

containing the request response, the deserialized catalog returned by
the server and array containing logs (log array will be empty if capture_logs is false)
    # File lib/puppet/http/service/compiler.rb
158 def post_catalog4(certname, persistence:, environment:, facts: nil, trusted_facts: nil, transaction_uuid: nil, job_id: nil, options: nil)
159   unless persistence.is_a?(Hash) && (missing = [:facts, :catalog] - persistence.keys.map(&:to_sym)).empty?
160     raise ArgumentError.new("The 'persistence' hash is missing the keys: #{missing.join(', ')}")
161   end
162   raise ArgumentError.new("Facts must be a Hash not a #{facts.class}") unless facts.nil? || facts.is_a?(Hash)
163   body = {
164     certname: certname,
165     persistence: persistence,
166     environment: environment,
167     transaction_uuid: transaction_uuid,
168     job_id: job_id,
169     options: options
170   }
171   body[:facts] = { values: facts } unless facts.nil?
172   body[:trusted_facts] = { values: trusted_facts } unless trusted_facts.nil?
173   headers = add_puppet_headers(
174     'Accept' => get_mime_types(Puppet::Resource::Catalog).join(', '),
175     'Content-Type' => 'application/json'
176   )
177 
178   url = URI::HTTPS.build(host: @url.host, port: @url.port, path: Puppet::Util.uri_encode("/puppet/v4/catalog"))
179   response = @client.post(
180     url,
181     body.to_json,
182     headers: headers
183   )
184   process_response(response)
185   begin
186     response_body = JSON.parse(response.body)
187     catalog = Puppet::Resource::Catalog.from_data_hash(response_body['catalog'])
188   rescue => err
189     raise Puppet::HTTP::SerializationError.new("Failed to deserialize catalog from puppetserver response: #{err.message}", err)
190   end
191   
192   logs = response_body['logs'] || []
193   [response, catalog, logs]
194 end
put_facts(name, environment:, facts:) click to toggle source

Submits a PUT request to submit facts for the node to the server.

@param [String] name Name of the node we are submitting facts for @param [String] environment Name of the environment we are operating in @param [Puppet::Node::Facts] facts Facts for the named node

@return [Puppet::HTTP::Response] The request response

@api public

    # File lib/puppet/http/service/compiler.rb
232 def put_facts(name, environment:, facts:)
233   formatter = Puppet::Network::FormatHandler.format_for(Puppet[:preferred_serialization_format])
234 
235   headers = add_puppet_headers(
236     'Accept' => get_mime_types(Puppet::Node::Facts).join(', '),
237     'Content-Type' => formatter.mime
238   )
239 
240   response = @client.put(
241     with_base_url("/facts/#{name}"),
242     serialize(formatter, facts),
243     headers: headers,
244     params: { environment: environment },
245   )
246 
247   process_response(response)
248 
249   response
250 end
put_filebucket_file(path, body:, environment:) click to toggle source

Submit a PUT request to store a file with filebucket.

@param [String] path The request path, formatted by `Puppet::FileBucket::Dipper` @param [String] body The contents of the file to be backed @param [String] environment Name of the environment we are operating in.

This should not impact filebucket at all, but is included to be consistent
with legacy code.

@return [Puppet::HTTP::Response] The response request

@api public

    # File lib/puppet/http/service/compiler.rb
302 def put_filebucket_file(path, body:, environment:)
303   headers = add_puppet_headers({
304     'Accept' => 'application/octet-stream',
305     'Content-Type' => 'application/octet-stream'
306     })
307 
308   response = @client.put(
309     with_base_url("/file_bucket_file/#{path}"),
310     body,
311     headers: headers,
312     params: {
313       environment: environment
314     }
315   )
316 
317   process_response(response)
318 
319   response
320 end