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.
trusted_information is specifically left out because we can’t serialize it and keep it “trusted”
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
# 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
# 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
# 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
# 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
# File lib/puppet/indirector/request.rb, line 102 def escaped_key URI.escape(key) end
# 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
# 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
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
# File lib/puppet/indirector/request.rb, line 115 def ignore_terminus? ignore_terminus end
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
# File lib/puppet/indirector/request.rb, line 153 def indirection_name=(name) @indirection_name = name.to_sym end
# File lib/puppet/indirector/request.rb, line 157 def model raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless i = indirection i.model end
Are we trying to interact with multiple resources, or just one?
# File lib/puppet/indirector/request.rb, line 163 def plural? method == :search end
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
# File lib/puppet/indirector/request.rb, line 266 def remote? self.node or self.ip end
# 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
# 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
# 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
# File lib/puppet/indirector/request.rb, line 75 def to_pson(*args) to_pson_data_hash.to_pson(*args) end
# File lib/puppet/indirector/request.rb, line 68 def to_pson_data_hash { 'document_type' => 'IndirectorRequest', 'data' => to_data_hash, } end
# File lib/puppet/indirector/request.rb, line 237 def to_s return(uri ? uri : "/#{indirection_name}/#{key}") end
# 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
# 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
# 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