Class: Runcible::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/runcible/base.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ Base

Returns a new instance of Base.



10
11
12
13
14
# File 'lib/runcible/base.rb', line 10

def initialize(config = {})
  @mutex = Mutex.new
  @config = config
  @logs = []
end

Instance Attribute Details

#logsObject

Returns the value of attribute logs.



8
9
10
# File 'lib/runcible/base.rb', line 8

def logs
  @logs
end

Instance Method Details

#add_http_auth_headerObject



176
177
178
# File 'lib/runcible/base.rb', line 176

def add_http_auth_header
  return {:user => config[:user], :password => config[:http_auth][:password]}
end

#add_oauth_header(method, path, headers) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/runcible/base.rb', line 180

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 = {}) ⇒ Object

rubocop:disable Metrics/AbcSize:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/runcible/base.rb', line 33

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

  self.logs << ([method.upcase, URI.join(client.url, path)] + args[1..-1]).join(': ')
  response = get_response(client, path, *args)
  processed = process_response(response)
  self.logs << "Response: #{response.code}: #{response.body}"
  log_info
  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) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/runcible/base.rb', line 98

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

#configObject



20
21
22
23
24
25
26
# 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)) ⇒ Object



87
88
89
# File 'lib/runcible/base.rb', line 87

def exception_to_log(exception, body = exception.try(:response).try(:body))
  "#{exception.message}: #{body}"
end

#format_payload_json(payload_hash) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/runcible/base.rb', line 118

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) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/runcible/base.rb', line 110

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) ⇒ Object



91
92
93
94
95
96
# File 'lib/runcible/base.rb', line 91

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) ⇒ Object



16
17
18
# File 'lib/runcible/base.rb', line 16

def lazy_config=(a_block)
  @mutex.synchronize { @lazy_config = a_block }
end

#log_debugObject



201
202
203
# File 'lib/runcible/base.rb', line 201

def log_debug
  self.config[:logging][:logger].debug(self.logs.join("\n")) if self.config[:logging][:debug]
end

#log_exceptionObject



205
206
207
# File 'lib/runcible/base.rb', line 205

def log_exception
  self.config[:logging][:logger].error(self.logs.join("\n")) if self.config[:logging][:exception]
end

#log_infoObject



209
210
211
# File 'lib/runcible/base.rb', line 209

def log_info
  self.config[:logging][:logger].info(self.logs.join("\n")) if self.config[:logging][:info]
end

#loggerObject



213
214
215
# File 'lib/runcible/base.rb', line 213

def logger
  self.config[:logging][:logger]
end

#path(*args) ⇒ Object



28
29
30
# File 'lib/runcible/base.rb', line 28

def path(*args)
  self.class.path(*args)
end

#process_response(response) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/runcible/base.rb', line 138

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 = []) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/runcible/base.rb', line 156

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