class PuppetDB::Client
Attributes
logger[W]
use_ssl[R]
Public Class Methods
new(settings = {}, query_api_version = 4, command_api_version = 1, admin_api_version = 1)
click to toggle source
# File lib/puppetdb/client.rb, line 31 def initialize(settings = {}, query_api_version = 4, command_api_version = 1, admin_api_version = 1) config = Config.new(settings, load_files: true) @query_api_version = query_api_version @command_api_version = command_api_version @admin_api_version = admin_api_version @servers = config.server_urls pem = config.pem token = config.token @servers.each do |server| scheme = URI.parse(server).scheme @use_ssl ||= scheme == 'https' unless %w[http https].include? scheme error_msg = "Configuration error: server_url '#{server}' must specify a protocol of either http or https" raise error_msg end end return unless @use_ssl unless hash_includes?(pem, :cacert, :cert, :key) || (pem[:cert].nil? && pem[:key].nil?) error_msg = 'Configuration error: https:// specified, but configuration is incomplete. It requires cacert and either cert and key, or a valid token.' raise error_msg end self.class.default_options = pem self.class.headers('X-Authentication' => token) if token self.class.connection_adapter(FixSSLConnectionAdapter) end
Public Instance Methods
command(command, payload, version)
click to toggle source
# File lib/puppetdb/client.rb, line 121 def command(command, payload, version) path = "/pdb/cmd/v#{@command_api_version}" query = { 'command' => command, 'version' => version, 'certname' => payload['certname'] } debug("#{path} #{query} #{payload}") self.class.base_uri(@servers.first) ret = self.class.post( path, query: query, body: payload.to_json, headers: { 'Accept' => 'application/json', 'Content-Type' => 'application/json' } ) raise_if_error(ret) Response.new(ret.parsed_response) end
debug(msg)
click to toggle source
# File lib/puppetdb/client.rb, line 27 def debug(msg) @logger.debug(msg) if @logger end
export(filename, opts = {})
click to toggle source
# File lib/puppetdb/client.rb, line 147 def export(filename, opts = {}) self.class.base_uri(@servers.first) anonymization_profile = opts.delete(:anonymization_profile) || 'none' path = "/pdb/admin/v#{@admin_api_version}/archive?anonymization_profile=#{anonymization_profile}" # Enforce stream_body to avoid using memory params = opts.merge(stream_body: true) File.open(filename, 'w') do |file| self.class.get(path, params) do |fragment| if [301, 302].include?(fragment.code) debug 'Skip streaming write for redirect' elsif fragment.code == 200 file.write(fragment) else raise StandardError, "Non-success status code while streaming #{fragment.code}" end end end end
hash_includes?(hash, *sought_keys)
click to toggle source
# File lib/puppetdb/client.rb, line 22 def hash_includes?(hash, *sought_keys) sought_keys.each { |x| return false unless hash.include?(x) } true end
import(filename)
click to toggle source
# File lib/puppetdb/client.rb, line 168 def import(filename) self.class.base_uri(@servers.first) path = "/pdb/admin/v#{@admin_api_version}/archive" self.class.post(path, body: { archive: File.open(filename) }) end
raise_if_error(response)
click to toggle source
# File lib/puppetdb/client.rb, line 62 def raise_if_error(response) raise UnauthorizedError, response if response.code == 401 raise ForbiddenError, response if response.code == 403 raise APIError, response if response.code.to_s =~ %r{^[4|5]} end
request(endpoint, query, opts = {})
click to toggle source
# File lib/puppetdb/client.rb, line 68 def request(endpoint, query, opts = {}) path = "/pdb/query/v#{@query_api_version}" if endpoint == '' # PQL json_query = query else path += "/#{endpoint}" query = PuppetDB::Query.maybe_promote(query) json_query = query.build end query_mode = opts.delete(:query_mode) || :first filtered_opts = { 'query' => json_query } opts.each do |k, v| if k == :counts_filter filtered_opts['counts-filter'] = JSON.dump(v) else filtered_opts[k.to_s.sub('_', '-')] = v end end debug("#{path} #{json_query} #{opts}") if query_mode == :first self.class.base_uri(@servers.first) ret = self.class.get(path, body: filtered_opts) raise_if_error(ret) total = ret.headers['X-Records'] total = ret.parsed_response.length if total.nil? Response.new(ret.parsed_response, total) elsif query_mode == :failover ret = nil @servers.each do |server| self.class.base_uri(server) ret = self.class.get(path, body: filtered_opts) if ret.code < 400 total = ret.headers['X-Records'] total = ret.parsed_response.length if total.nil? return Response.new(ret.parsed_response, total) else debug("query on '#{server}' failed with #{ret.code}") end end raise APIError, ret else raise ArgumentError, "Query mode '#{query_mode}' is not supported (try :first or :failover)." end end
status()
click to toggle source
# File lib/puppetdb/client.rb, line 174 def status status_endpoint = '/status/v1/services' status_map = {} @servers.each do |server| self.class.base_uri(server) ret = self.class.get(status_endpoint) status_map[server] = if ret.code >= 400 { error: "Unable to build JSON object from server: #{server}" } else ret.parsed_response end end status_map end