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