Class: ChefAPI::Connection
- Inherits:
-
Object
- Object
- ChefAPI::Connection
- Includes:
- Configurable, Logger
- Defined in:
- lib/chef-api/connection.rb
Overview
Connection object for the ChefAPI API.
Class Method Summary collapse
Instance Method Summary collapse
-
#build_uri(verb, path, params = {}) ⇒ URI
Construct a URL from the given verb and path.
-
#class_for_request(verb) ⇒ Class
Helper method to get the corresponding Net::HTTP class from the given HTTP verb.
-
#delete(path, params = {}) ⇒ String, Hash
Make a HTTP DELETE request.
-
#get(path, params = {}) ⇒ String, Hash
Make a HTTP GET request.
-
#initialize(options = {}) ⇒ ChefAPI::Connection
constructor
Create a new ChefAPI Connection with the given options.
-
#patch(path, data) ⇒ String, Hash
Make a HTTP PATCH request.
-
#post(path, data) ⇒ String, Hash
Make a HTTP POST request.
-
#put(path, data) ⇒ String, Hash
Make a HTTP PUT request.
-
#request(verb, path, data = {}) ⇒ String, Hash
Make an HTTP request with the given verb, data, params, and headers.
-
#same_options?(opts) ⇒ Boolean
Determine if the given options are the same as ours.
-
#to_query_string(hash) ⇒ String?
Convert the given hash to a list of query string parameters.
Methods included from Logger
included, level, level=, logger_for
Methods included from Configurable
Constructor Details
#initialize(options = {}) ⇒ ChefAPI::Connection
Create a new ChefAPI Connection with the given options. Any options given take precedence over the default options.
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/chef-api/connection.rb', line 48 def initialize( = {}) # Use any options given, but fall back to the defaults set on the module ChefAPI::Configurable.keys.each do |key| value = if [key].nil? ChefAPI.instance_variable_get(:"@#{key}") else [key] end instance_variable_set(:"@#{key}", value) end end |
Class Method Details
.proxy(name, klass) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/chef-api/connection.rb', line 30 def proxy(name, klass) class_eval " def \#{name}\n @\#{name} ||= ChefAPI::Proxy.new(self, \#{klass})\n end\n EOH\nend\n", __FILE__, __LINE__ + 1 |
Instance Method Details
#build_uri(verb, path, params = {}) ⇒ URI
Construct a URL from the given verb and path. If the request is a GET or DELETE request, the params are assumed to be query params are are converted as such using #to_query_string.
If the path is relative, it is merged with the Defaults.endpoint attribute. If the path is absolute, it is converted to a URI object and returned.
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/chef-api/connection.rb', line 252 def build_uri(verb, path, params = {}) log.info "===> Building URI..." # Add any query string parameters if [:delete, :get].include?(verb) log.debug " Detected verb deserves a querystring" log.debug " Building querystring using #{params.inspect}" path = [path, to_query_string(params)].compact.join('?') end # Parse the URI uri = URI.parse(path) # Don't merge absolute URLs unless uri.absolute? log.debug " Detected URI is relative" log.debug " Appending #{endpoint} to #{path}" uri = URI.parse(File.join(endpoint, path)) end # Return the URI object uri end |
#class_for_request(verb) ⇒ Class
Helper method to get the corresponding Net::HTTP class from the given HTTP verb.
285 286 287 |
# File 'lib/chef-api/connection.rb', line 285 def class_for_request(verb) Net::HTTP.const_get(verb.to_s.capitalize) end |
#delete(path, params = {}) ⇒ String, Hash
Make a HTTP DELETE request
133 134 135 |
# File 'lib/chef-api/connection.rb', line 133 def delete(path, params = {}) request(:delete, path, params) end |
#get(path, params = {}) ⇒ String, Hash
Make a HTTP GET request
80 81 82 |
# File 'lib/chef-api/connection.rb', line 80 def get(path, params = {}) request(:get, path, params) end |
#patch(path, data) ⇒ String, Hash
Make a HTTP PATCH request
120 121 122 |
# File 'lib/chef-api/connection.rb', line 120 def patch(path, data) request(:patch, path, data) end |
#post(path, data) ⇒ String, Hash
Make a HTTP POST request
94 95 96 |
# File 'lib/chef-api/connection.rb', line 94 def post(path, data) request(:post, path, data) end |
#put(path, data) ⇒ String, Hash
Make a HTTP PUT request
107 108 109 |
# File 'lib/chef-api/connection.rb', line 107 def put(path, data) request(:put, path, data) end |
#request(verb, path, data = {}) ⇒ String, Hash
Make an HTTP request with the given verb, data, params, and headers. If the response has a return type of JSON, the JSON is automatically parsed and returned as a hash; otherwise it is returned as a string.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/chef-api/connection.rb', line 158 def request(verb, path, data = {}) log.info "===> #{verb.to_s.upcase} #{path}..." # Build the URI and request object from the given information uri = build_uri(verb, path, data) request = class_for_request(verb).new(uri.request_uri) # Add request headers add_request_headers(request) # Setup PATCH/POST/PUT if [:patch, :post, :put].include?(verb) if data.respond_to?(:read) request.body_stream = data elsif data.is_a?(Hash) request.form_data = data else request.body = data end end # Sign the request add_signing_headers(verb, uri, request, parsed_key) # Create the HTTP connection object - since the proxy information defaults # to +nil+, we can just pass it to the initializer method instead of doing # crazy strange conditionals. connection = Net::HTTP.new(uri.host, uri.port, proxy_address, proxy_port, proxy_username, proxy_password) # Apply SSL, if applicable if uri.scheme == 'https' # Turn on SSL connection.use_ssl = true # Custom pem files, no problem! if ssl_pem_file pem = File.read(ssl_pem_file) connection.cert = OpenSSL::X509::Certificate.new(pem) connection.key = OpenSSL::PKey::RSA.new(pem) connection.verify_mode = OpenSSL::SSL::VERIFY_PEER end # Naughty, naughty, naughty! Don't blame when when someone hops in # and executes a MITM attack! unless ssl_verify log.warn "===> Disabling SSL verification..." log.warn "Neither ChefAPI nor the maintainers are responsible for " \ "damanges incurred as a result of disabling SSL verification. " \ "Please use this with extreme caution, or consider specifying " \ "a custom certificate using `config.ssl_pem_file'." connection.verify_mode = OpenSSL::SSL::VERIFY_NONE end end # Create a connection using the block form, which will ensure the socket # is properly closed in the event of an error. connection.start do |http| response = http.request(request) case response when Net::HTTPRedirection redirect = URI.parse(response['location']) log.debug "===> Performing HTTP redirect to #{redirect}" request(verb, redirect, params) when Net::HTTPSuccess success(response) else error(response) end end rescue SocketError, Errno::ECONNREFUSED, EOFError log.warn " Unable to reach the Chef Server" raise Error::HTTPServerUnavailable.new end |
#same_options?(opts) ⇒ Boolean
Determine if the given options are the same as ours.
66 67 68 |
# File 'lib/chef-api/connection.rb', line 66 def (opts) opts.hash == .hash end |
#to_query_string(hash) ⇒ String?
Convert the given hash to a list of query string parameters. Each key and value in the hash is URI-escaped for safety.
299 300 301 302 303 |
# File 'lib/chef-api/connection.rb', line 299 def to_query_string(hash) hash.map do |key, value| "#{URI.escape(key.to_s)}=#{URI.escape(value.to_s)}" end.join('&')[/.+/] end |