# 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