class Runcible::Base

Attributes

logs[RW]

Public Class Methods

new(config = {}) click to toggle source
# File lib/runcible/base.rb, line 10
def initialize(config = {})
  @mutex = Mutex.new
  @config = config
  @logs = []
end

Public Instance Methods

add_http_auth_header() click to toggle source
# File lib/runcible/base.rb, line 178
def add_http_auth_header
  return {:user => config[:user], :password => config[:http_auth][:password]}
end
add_oauth_header(method, path, headers) click to toggle source
# File lib/runcible/base.rb, line 182
def add_oauth_header(method, path, headers)
  default_options = { :site               => config[:url],
                      :http_method        => method,
                      :request_token_path => '',
                      :authorize_path     => '',
                      :access_token_path  => '' }

  consumer = OAuth::Consumer.new(config[:oauth][:oauth_key], config[:oauth][:oauth_secret], default_options)

  method_to_http_request = { :get    => Net::HTTP::Get,
                             :post   => Net::HTTP::Post,
                             :put    => Net::HTTP::Put,
                             :delete => Net::HTTP::Delete }

  http_request = method_to_http_request[method].new(path)
  consumer.sign!(http_request)

  headers['Authorization'] = http_request['Authorization']
  return headers
end
call(method, path, options = {}) click to toggle source

rubocop:disable Metrics/AbcSize: rubocop:disable PerceivedComplexity

# File lib/runcible/base.rb, line 34
def call(method, path, options = {})
  self.logs = []
  clone_config = self.config.clone
  #on occation path will already have prefix (sync cancel)
  path = clone_config[:api_path] + path unless path.start_with?(clone_config[:api_path])

  headers = clone_config[:headers].clone

  get_params = options[:params] if options[:params]
  path = combine_get_params(path, get_params) if get_params

  client_options = {}
  client_options[:timeout] = clone_config[:timeout] if clone_config[:timeout]
  client_options[:open_timeout] = clone_config[:open_timeout] if clone_config[:open_timeout]
  client_options[:verify_ssl] = clone_config[:verify_ssl] unless clone_config[:verify_ssl].nil?

  if clone_config[:oauth]
    self.logger.warn('[DEPRECATION] Pulp oauth is deprecated.  Please use cert_auth instead.')
    headers = add_oauth_header(method, path, headers)
    headers['pulp-user'] = clone_config[:user]
  elsif clone_config[:cert_auth]
    if !clone_config[:cert_auth][:ssl_client_cert] || !clone_config[:cert_auth][:ssl_client_key]
      fail Runcible::ConfigurationUndefinedError, "Missing SSL certificate or key configuration."
    end
    client_options[:ssl_client_cert] = clone_config[:cert_auth][:ssl_client_cert]
    client_options[:ssl_client_key] = clone_config[:cert_auth][:ssl_client_key]
  else
    client_options[:user] = clone_config[:user]
    client_options[:password] = config[:http_auth][:password]
  end

  client_options[:ssl_ca_file] = config[:ca_cert_file] unless config[:ca_cert_file].nil?
  client = RestClient::Resource.new(clone_config[:url], client_options)

  args = [method]
  args << generate_payload(options) if [:post, :put].include?(method)
  args << headers
  starting_arg = options[:no_log_payload] == true ? 2 : 1
  self.logs << ([method.upcase, URI.join(client.url, path)] + args[starting_arg..-1]).join(': ')

  response = get_response(client, path, *args)
  processed = process_response(response)
  self.logs << "Response: #{response.code}: #{response.body}"
  log_debug
  processed
rescue RestClient::ResourceNotFound => e
  self.logs << exception_to_log(e)
  log_info
  raise e
rescue => e
  self.logs << exception_to_log(e)
  log_exception
  raise e
end
combine_get_params(path, params) click to toggle source
# File lib/runcible/base.rb, line 100
def combine_get_params(path, params)
  query_string = params.map do |k, v|
    if v.is_a? Array
      v.map { |y| "#{k}=#{y}" }.join('&')
    else
      "#{k}=#{v}"
    end
  end
  query_string = query_string.flatten.join('&')
  path + "?#{query_string}"
end
config() click to toggle source
# File lib/runcible/base.rb, line 20
def config
  @mutex.synchronize do
    @config = @lazy_config.call if defined?(@lazy_config)
    fail Runcible::ConfigurationUndefinedError, Runcible::ConfigurationUndefinedError.message unless @config
    @config
  end
end
exception_to_log(exception, body = exception.try(:response).try(:body)) click to toggle source
# File lib/runcible/base.rb, line 89
def exception_to_log(exception, body = exception.try(:response).try(:body))
  "#{exception.message}: #{body}"
end
filter_sensitive_data(payload) click to toggle source
# File lib/runcible/base.rb, line 207
def filter_sensitive_data(payload)
  payload.gsub(/-----BEGIN RSA PRIVATE KEY-----[\s\S]*-----END RSA PRIVATE KEY-----/, '[private key filtered]')
end
format_payload_json(payload_hash) click to toggle source
# File lib/runcible/base.rb, line 120
def format_payload_json(payload_hash)
  if payload_hash
    if payload_hash[:optional]
      payload = if payload_hash[:required]
                  payload_hash[:required].merge(payload_hash[:optional])
                else
                  payload_hash[:optional]
                end
    elsif payload_hash[:delta]
      payload = payload_hash
    else
      payload = payload_hash[:required]
    end
  else
    payload = {}
  end

  return payload.to_json
end
generate_payload(options) click to toggle source
# File lib/runcible/base.rb, line 112
def generate_payload(options)
  if options[:payload].is_a?(String)
    return options[:payload]
  elsif options[:payload].is_a?(Hash)
    format_payload_json(options[:payload])
  end
end
get_response(client, path, *args) click to toggle source
# File lib/runcible/base.rb, line 93
def get_response(client, path, *args)
  client[path].send(*args) do |response, _request, _result, &_block|
    resp = response.return!
    return resp
  end
end
lazy_config=(a_block) click to toggle source
# File lib/runcible/base.rb, line 16
def lazy_config=(a_block)
  @mutex.synchronize { @lazy_config = a_block }
end
log_debug() click to toggle source
# File lib/runcible/base.rb, line 211
def log_debug
  logger.debug(log_message) if self.config[:logging][:debug]
end
log_exception() click to toggle source
# File lib/runcible/base.rb, line 215
def log_exception
  logger.error(log_message) if self.config[:logging][:exception]
end
log_info() click to toggle source
# File lib/runcible/base.rb, line 219
def log_info
  logger.info(log_message) if self.config[:logging][:info]
end
log_message() click to toggle source
# File lib/runcible/base.rb, line 203
def log_message
  filter_sensitive_data(self.logs.join("\n"))
end
logger() click to toggle source
# File lib/runcible/base.rb, line 223
def logger
  self.config[:logging][:logger]
end
path(*args) click to toggle source
# File lib/runcible/base.rb, line 28
def path(*args)
  self.class.path(*args)
end
process_response(response) click to toggle source
# File lib/runcible/base.rb, line 140
def process_response(response)
  begin
    body = response.body == "null" ? nil : JSON.parse(response.body)
    if body.respond_to? :with_indifferent_access
      body = body.with_indifferent_access
    elsif body.is_a? Array
      body = body.map do |i|
        i.respond_to?(:with_indifferent_access) ? i.with_indifferent_access : i
      end
    end
    response = Runcible::Response.new(body, response)
  rescue JSON::ParserError => e
    self.logs << "Unable to parse JSON: #{e.message}"
  end

  return response
end
required_params(local_names, binding, keys_to_remove = []) click to toggle source
# File lib/runcible/base.rb, line 158
def required_params(local_names, binding, keys_to_remove = [])
  local_names = local_names.each_with_object({}) do |v, acc|
    value = binding.eval(v.to_s) unless v == :_
    acc[v] = value unless value.nil?
    acc
  end

  #The double delete is to support 1.8.7 and 1.9.3
  local_names.delete(:payload)
  local_names.delete(:optional)
  local_names.delete('payload')
  local_names.delete('optional')
  keys_to_remove.each do |key|
    local_names.delete(key)
    local_names.delete(key.to_sym)
  end

  return local_names
end