# class Puppet::Indirector::Request

This class encapsulates all of the information you need to make an Indirection call, and as a a result also handles REST calls. It’s somewhat analogous to an HTTP Request object, except tuned for our Indirector.

### Constants

OPTION_ATTRIBUTES

### Attributes

authenticated[RW]
ignore_cache[RW]
ignore_terminus[RW]
indirection_name[R]
instance[RW]
ip[RW]
key[RW]
method[RW]
node[RW]
options[RW]
port[RW]
protocol[RW]
server[RW]
uri[RW]

### Public Class Methods

from_pson(json) click to toggle source

    # File lib/puppet/indirector/request.rb, line 21
    def self.from_pson(json)
      raise ArgumentError, "No indirection name provided in json data" unless indirection_name = json['type']
      raise ArgumentError, "No method name provided in json data" unless method = json['method']
      raise ArgumentError, "No key provided in json data" unless key = json['key']

      request = new(indirection_name, method, key, nil, json['attributes'])

      if instance = json['instance']
        klass = Puppet::Indirector::Indirection.instance(request.indirection_name).model
        if instance.is_a?(klass)
          request.instance = instance
        else
          request.instance = klass.from_pson(instance)
        end
      end

      request
    end

new(indirection_name, method, key, instance, options = {}) click to toggle source

    # File lib/puppet/indirector/request.rb, line 101
    def initialize(indirection_name, method, key, instance, options = {})
      @instance = instance
      options ||= {}

      self.indirection_name = indirection_name
      self.method = method

      options = options.inject({}) { |hash, ary| hash[ary[0].to_sym] = ary[1]; hash }

      set_attributes(options)

      @options = options

      if key
        # If the request key is a URI, then we need to treat it specially,
        # because it rewrites the key.  We could otherwise strip server/port/etc
        # info out in the REST class, but it seemed bad design for the REST
        # class to rewrite the key.

        if key.to_s =~ /^\w+:\// and not Puppet::Util.absolute_path?(key.to_s) # it's a URI
          set_uri_key(key)
        else
          @key = key
        end
      end

      @key = @instance.name if ! @key and @instance
    end

### Public Instance Methods

authenticated?() click to toggle source

Is this an authenticated request?

    # File lib/puppet/indirector/request.rb, line 67
    def authenticated?
      # Double negative, so we just get true or false
      ! ! authenticated
    end

do_request(srv_service=:puppet, default_server=Puppet.settings[:server], default_port=Puppet.settings[:masterport]) { |self| ... } click to toggle source

    # File lib/puppet/indirector/request.rb, line 193
    def do_request(srv_service=:puppet, default_server=Puppet.settings[:server], default_port=Puppet.settings[:masterport], &block)
      # We were given a specific server to use, so just use that one.
      # This happens if someone does something like specifying a file
      # source using a puppet:// URI with a specific server.
      return yield(self) if !self.server.nil?

      if Puppet.settings[:use_srv_records]
        Puppet::Network::Resolver.each_srv_record(Puppet.settings[:srv_domain], srv_service) do |srv_server, srv_port|
          begin
            self.server = srv_server
            self.port   = srv_port
            return yield(self)
          rescue SystemCallError => e
            Puppet.warning "Error connecting to #{srv_server}:#{srv_port}: #{e.message}"
          end
        end
      end

      # ... Fall back onto the default server.
      Puppet.debug "No more servers left, falling back to #{default_server}:#{default_port}" if Puppet.settings[:use_srv_records]
      self.server = default_server
      self.port   = default_port
      return yield(self)
    end

environment() click to toggle source

    # File lib/puppet/indirector/request.rb, line 72
    def environment
      @environment ||= Puppet::Node::Environment.new
    end

environment=(env) click to toggle source

    # File lib/puppet/indirector/request.rb, line 76
    def environment=(env)
      @environment = if env.is_a?(Puppet::Node::Environment)
        env
      else
        Puppet::Node::Environment.new(env)
      end
    end

escaped_key() click to toggle source

    # File lib/puppet/indirector/request.rb, line 84
    def escaped_key
      URI.escape(key)
    end

ignore_cache?() click to toggle source

LAK:NOTE This is a messy interface to the cache, and it’s only used by the Configurer class. I decided it was better to implement it now and refactor later, when we have a better design, than to spend another month coming up with a design now that might not be any better.

    # File lib/puppet/indirector/request.rb, line 93
    def ignore_cache?
      ignore_cache
    end

ignore_terminus?() click to toggle source

    # File lib/puppet/indirector/request.rb, line 97
    def ignore_terminus?
      ignore_terminus
    end

indirection() click to toggle source

Look up the indirection based on the name provided.

    # File lib/puppet/indirector/request.rb, line 131
    def indirection
      Puppet::Indirector::Indirection.instance(indirection_name)
    end

indirection_name=(name) click to toggle source

    # File lib/puppet/indirector/request.rb, line 135
    def indirection_name=(name)
      @indirection_name = name.to_sym
    end

model() click to toggle source

    # File lib/puppet/indirector/request.rb, line 140
    def model
      raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless i = indirection
      i.model
    end

plural?() click to toggle source

Are we trying to interact with multiple resources, or just one?

    # File lib/puppet/indirector/request.rb, line 155
    def plural?
      method == :search
    end

query_string() click to toggle source

Create the query string, if options are present.

    # File lib/puppet/indirector/request.rb, line 160
    def query_string
      return "" unless options and ! options.empty?
      "?" + options.collect do |key, value|
        case value
        when nil; next
        when true, false; value = value.to_s
        when Fixnum, Bignum, Float; value = value # nothing
        when String; value = CGI.escape(value)
        when Symbol; value = CGI.escape(value.to_s)
        when Array; value = CGI.escape(YAML.dump(value))
        else
          raise ArgumentError, "HTTP REST queries cannot handle values of type '#{value.class}'"
        end

        "#{key}=#{value}"
      end.join("&")
    end

remote?() click to toggle source

    # File lib/puppet/indirector/request.rb, line 218
    def remote?
      self.node or self.ip
    end

to_hash() click to toggle source

    # File lib/puppet/indirector/request.rb, line 178
    def to_hash
      result = options.dup

      OPTION_ATTRIBUTES.each do |attribute|
        if value = send(attribute)
          result[attribute] = value
        end
      end
      result
    end

to_pson(*args) click to toggle source

    # File lib/puppet/indirector/request.rb, line 40
    def to_pson(*args)
      result = {
        'document_type' => 'IndirectorRequest',
        'data' => {
          'type' => indirection_name,
          'method' => method,
          'key' => key
        }
      }
      data = result['data']
      attributes = {}
      OPTION_ATTRIBUTES.each do |key|
        next unless value = send(key)
        attributes[key] = value
      end

      options.each do |opt, value|
        attributes[opt] = value
      end

      data['attributes'] = attributes unless attributes.empty?
      data['instance'] = instance if instance

      result.to_pson(*args)
    end

to_s() click to toggle source

    # File lib/puppet/indirector/request.rb, line 189
    def to_s
      return(uri ? uri : "/#{indirection_name}/#{key}")
    end

use_cache?() click to toggle source

Should we allow use of the cached object?

    # File lib/puppet/indirector/request.rb, line 146
    def use_cache?
      if defined?(@use_cache)
        ! ! use_cache
      else
        true
      end
    end