class Catalog::Compiler

Attributes

code[RW]

Public Class Methods

new() click to toggle source
# File lib/puppet/indirector/catalog/compiler.rb, line 56
def initialize
  set_server_facts
end

Public Instance Methods

extract_facts_from_request(request) click to toggle source
# File lib/puppet/indirector/catalog/compiler.rb, line 13
def extract_facts_from_request(request)
  return unless text_facts = request.options[:facts]
  unless format = request.options[:facts_format]
    raise ArgumentError, "Facts but no fact format provided for #{request.key}"
  end

  # If the facts were encoded as yaml, then the param reconstitution system
  # in Network::HTTP::Handler will automagically deserialize the value.
  if text_facts.is_a?(Puppet::Node::Facts)
    facts = text_facts
  else
    facts = Puppet::Node::Facts.convert_from(format, text_facts)
  end

  unless facts.name == request.key
    raise Puppet::Error, "Catalog for #{request.key.inspect} was requested with fact definition for the wrong node (#{facts.name.inspect})."
  end

  facts.add_timestamp
  Puppet::Node::Facts.indirection.save(facts)
end
filter(catalog) click to toggle source

filter-out a catalog to remove exported resources

# File lib/puppet/indirector/catalog/compiler.rb, line 51
def filter(catalog)
  return catalog.filter { |r| r.virtual? } if catalog.respond_to?(:filter)
  catalog
end
find(request) click to toggle source

Compile a node’s catalog.

# File lib/puppet/indirector/catalog/compiler.rb, line 36
def find(request)
  extract_facts_from_request(request)

  node = node_from_request(request)

  if catalog = compile(node)
    return catalog
  else
    # This shouldn't actually happen; we should either return
    # a config or raise an exception.
    return nil
  end
end
networked?() click to toggle source

Is our compiler part of a network, or are we just local?

# File lib/puppet/indirector/catalog/compiler.rb, line 61
def networked?
  Puppet.run_mode.master?
end

Private Instance Methods

add_node_data(node) click to toggle source

Add any extra data necessary to the node.

# File lib/puppet/indirector/catalog/compiler.rb, line 68
def add_node_data(node)
  # Merge in our server-side facts, so they can be used during compilation.
  node.merge(@server_facts)
end
compile(node) click to toggle source

Compile the actual catalog.

# File lib/puppet/indirector/catalog/compiler.rb, line 74
def compile(node)
  str = "Compiled catalog for #{node.name}"
  str += " in environment #{node.environment}" if node.environment
  config = nil

  loglevel = networked? ? :notice : :none

  benchmark(loglevel, str) do
    begin
      config = Puppet::Parser::Compiler.compile(node)
    rescue Puppet::Error => detail
      Puppet.err(detail.to_s) if networked?
      raise
    end
  end

  config
end
find_node(name, *args) click to toggle source

Turn our host name into a node object.

# File lib/puppet/indirector/catalog/compiler.rb, line 94
def find_node(name, *args)
  begin
    return nil unless node = Puppet::Node.indirection.find(name, *args)
  rescue => detail
    message = "Failed when searching for node #{name}: #{detail}"
    Puppet.log_exception(detail, message)
    raise Puppet::Error, message
  end


  # Add any external data to the node.
  add_node_data(node)

  node
end
node_from_request(request) click to toggle source

Extract the node from the request, or use the request to find the node.

# File lib/puppet/indirector/catalog/compiler.rb, line 112
def node_from_request(request)
  if node = request.options[:use_node]
    if request.remote?
      raise Puppet::Error, "Invalid option use_node for a remote request"
    else
      return node
    end
  end

  # We rely on our authorization system to determine whether the connected
  # node is allowed to compile the catalog's node referenced by key.
  # By default the REST authorization system makes sure only the connected node
  # can compile his catalog.
  # This allows for instance monitoring systems or puppet-load to check several
  # node's catalog with only one certificate and a modification to auth.conf 
  # If no key is provided we can only compile the currently connected node.
  name = request.key || request.node
  if node = find_node(name, :environment => request.environment)
    return node
  end

  raise ArgumentError, "Could not find node '#{name}'; cannot compile"
end
set_server_facts() click to toggle source

Initialize our server fact hash; we add these to each client, and they won’t change while we’re running, so it’s safe to cache the values.

# File lib/puppet/indirector/catalog/compiler.rb, line 138
def set_server_facts
  @server_facts = {}

  # Add our server version to the fact list
  @server_facts["serverversion"] = Puppet.version.to_s

  # And then add the server name and IP
  {"servername" => "fqdn",
    "serverip" => "ipaddress"
  }.each do |var, fact|
    if value = Facter.value(fact)
      @server_facts[var] = value
    else
      Puppet.warning "Could not retrieve fact #{fact}"
    end
  end

  if @server_facts["servername"].nil?
    host = Facter.value(:hostname)
    if domain = Facter.value(:domain)
      @server_facts["servername"] = [host, domain].join(".")
    else
      @server_facts["servername"] = host
    end
  end
end