class Puppet::Indirector::Request

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

Constants

OPTION_ATTRIBUTES

trusted_information is specifically left out because we can’t serialize it and keep it “trusted”

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 Instance Methods

authenticated?() click to toggle source

Is this an authenticated request?

# File lib/puppet/indirector/request.rb, line 80
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 241
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
encode_params(params) click to toggle source
# File lib/puppet/indirector/request.rb, line 220
def encode_params(params)
  params.collect do |key, value|
    "#{key}=#{CGI.escape(value.to_s)}"
  end.join("&")
end
environment() click to toggle source
# File lib/puppet/indirector/request.rb, line 85
def environment
  # If environment has not been set directly, we should use the application's
  # current environment
  @environment ||= Puppet.lookup(:current_environment)
end
environment=(env) click to toggle source
# File lib/puppet/indirector/request.rb, line 91
def environment=(env)
  @environment =
  if env.is_a?(Puppet::Node::Environment)
    env
  elsif (current_environment = Puppet.lookup(:current_environment)).name == env
    current_environment
  else
    Puppet.lookup(:environments).get!(env)
  end
end
escaped_key() click to toggle source
# File lib/puppet/indirector/request.rb, line 102
def escaped_key
  URI.escape(key)
end
expand_into_parameters(data) click to toggle source
# File lib/puppet/indirector/request.rb, line 191
def expand_into_parameters(data)
  data.inject([]) do |params, key_value|
    key, value = key_value

    expanded_value = case value
                     when Array
                       value.collect { |val| [key, val] }
                     else
                       [key_value]
                     end

    params.concat(expand_primitive_types_into_parameters(expanded_value))
  end
end
expand_primitive_types_into_parameters(data) click to toggle source
# File lib/puppet/indirector/request.rb, line 206
def expand_primitive_types_into_parameters(data)
  data.inject([]) do |params, key_value|
    key, value = key_value
    case value
    when nil
      params
    when true, false, String, Symbol, Fixnum, Bignum, Float
      params << [key, value]
    else
      raise ArgumentError, "HTTP REST queries cannot handle values of type '#{value.class}'"
    end
  end
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 111
def ignore_cache?
  ignore_cache
end
ignore_terminus?() click to toggle source
# File lib/puppet/indirector/request.rb, line 115
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 149
def indirection
  Puppet::Indirector::Indirection.instance(indirection_name)
end
indirection_name=(name) click to toggle source
# File lib/puppet/indirector/request.rb, line 153
def indirection_name=(name)
  @indirection_name = name.to_sym
end
model() click to toggle source
# File lib/puppet/indirector/request.rb, line 157
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 163
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 168
def query_string
  return "" if options.nil? || options.empty?

  # For backward compatibility with older (pre-3.3) masters,
  # this puppet option allows serialization of query parameter
  # arrays as yaml.  This can be removed when we remove yaml
  # support entirely.
  if Puppet.settings[:legacy_query_parameter_serialization]
    replace_arrays_with_yaml
  end

  "?" + encode_params(expand_into_parameters(options.to_a))
end
remote?() click to toggle source
# File lib/puppet/indirector/request.rb, line 266
def remote?
  self.node or self.ip
end
replace_arrays_with_yaml() click to toggle source
# File lib/puppet/indirector/request.rb, line 182
def replace_arrays_with_yaml
  options.each do |key, value|
    case value
      when Array
        options[key] = YAML.dump(value)
    end
  end
end
to_data_hash() click to toggle source
# File lib/puppet/indirector/request.rb, line 47
def to_data_hash
  result = {
    'type' => indirection_name,
    'method' => method,
    'key' => key
  }
  attributes = {}
  OPTION_ATTRIBUTES.each do |key|
    next unless value = send(key)
    attributes[key] = value
  end

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

  result['attributes'] = attributes unless attributes.empty?
  result['instance'] = instance if instance
  result
end
to_hash() click to toggle source
# File lib/puppet/indirector/request.rb, line 226
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 75
def to_pson(*args)
  to_pson_data_hash.to_pson(*args)
end
to_pson_data_hash() click to toggle source
# File lib/puppet/indirector/request.rb, line 68
def to_pson_data_hash
  {
    'document_type' => 'IndirectorRequest',
    'data' => to_data_hash,
  }
end
to_s() click to toggle source
# File lib/puppet/indirector/request.rb, line 237
def to_s
  return(uri ? uri : "/#{indirection_name}/#{key}")
end

Public Class Methods

from_data_hash(data) click to toggle source
# File lib/puppet/indirector/request.rb, line 23
def self.from_data_hash(data)
  raise ArgumentError, "No indirection name provided in data" unless indirection_name = data['type']
  raise ArgumentError, "No method name provided in data" unless method = data['method']
  raise ArgumentError, "No key provided in data" unless key = data['key']

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

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

  request
end
from_pson(json) click to toggle source
# File lib/puppet/indirector/request.rb, line 42
def self.from_pson(json)
  Puppet.deprecation_warning("from_pson is being removed in favour of from_data_hash.")
  self.from_data_hash(json)
end
new(indirection_name, method, key, instance, options = {}) click to toggle source
# File lib/puppet/indirector/request.rb, line 119
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