Class: ChefAPI::Connection
- Inherits:
-
Object
- Object
- ChefAPI::Connection
- Includes:
- Configurable, Logify
- 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. -
#clients ⇒ Class<Resource::Client>
Get the list of clients for this Connection.
-
#cookbooks ⇒ Class<Resource::Cookbook>
Get the list of cookbooks for this Connection.
-
#data_bag_item ⇒ Class<Resource::DataBagItem>
Get the list of data_bag_item for this Connection.
-
#data_bags ⇒ Class<Resource::DataBag>
Get the list of data_bags for this Connection.
-
#delete(path, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP DELETE request.
-
#environments ⇒ Class<Resource::Environment>
Get the list of environments for this Connection.
-
#get(path, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP GET request.
-
#groups ⇒ Class<Resource::Group>
Get the list of groups for this Connection.
-
#initialize(options = {}) {|_self| ... } ⇒ ChefAPI::Connection
constructor
Create a new ChefAPI Connection with the given options.
-
#nodes ⇒ Class<Resource::Node>
Get the list of nodes for this Connection.
-
#organizations ⇒ Class<Resource::Organization>
Get the list of organizations for this Connection.
-
#partial_search ⇒ Class<Resource::PartialSearch>
Get the list of partial_search for this Connection.
-
#patch(path, data, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP PATCH request.
-
#post(path, data, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP POST request.
-
#principals ⇒ Class<Resource::Principal>
Get the list of principals for this Connection.
-
#put(path, data, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP PUT request.
-
#request(verb, path, data = {}, params = {}, request_options = {}) ⇒ String, Hash
Make an HTTP request with the given verb, data, params, and headers.
-
#roles ⇒ Class<Resource::Role>
Get the list of roles for this Connection.
-
#same_options?(opts) ⇒ Boolean
Determine if the given options are the same as ours.
-
#search ⇒ Class<Resource::Search>
Get the list of search for this Connection.
-
#to_query_string(hash) ⇒ String?
Convert the given hash to a list of query string parameters.
-
#users ⇒ Class<Resource::User>
Get the list of users for this Connection.
Methods included from Configurable
Constructor Details
#initialize(options = {}) {|_self| ... } ⇒ ChefAPI::Connection
Create a new ChefAPI Connection with the given options. Any options given take precedence over the default options.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/chef-api/connection.rb', line 74 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 yield self if block_given? end |
Class Method Details
.proxy(name, klass) ⇒ Object
27 28 29 30 31 32 33 34 |
# File 'lib/chef-api/connection.rb', line 27 def proxy(name, klass) class_eval <<-EOH, __FILE__, __LINE__ + 1 def #{name} Thread.current['chefapi.connection'] = self #{klass} end EOH end |
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.
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/chef-api/connection.rb', line 330 def build_uri(verb, path, params = {}) log.info "Building URI..." # Add any query string parameters if querystring = to_query_string(params) log.debug "Detected verb deserves a querystring" log.debug "Building querystring using #{params.inspect}" log.debug "Compiled querystring is #{querystring.inspect}" path = [path, querystring].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 #{path} to #{endpoint}" 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.
364 365 366 |
# File 'lib/chef-api/connection.rb', line 364 def class_for_request(verb) Net::HTTP.const_get(verb.to_s.capitalize) end |
#clients ⇒ Class<Resource::Client>
Get the list of clients for this ChefAPI::Connection. This method is threadsafe.
40 |
# File 'lib/chef-api/connection.rb', line 40 proxy :clients, 'Resource::Client' |
#cookbooks ⇒ Class<Resource::Cookbook>
Get the list of cookbooks for this ChefAPI::Connection. This method is threadsafe.
41 |
# File 'lib/chef-api/connection.rb', line 41 proxy :cookbooks, 'Resource::Cookbook' |
#data_bag_item ⇒ Class<Resource::DataBagItem>
Get the list of data_bag_item for this ChefAPI::Connection. This method is threadsafe.
43 |
# File 'lib/chef-api/connection.rb', line 43 proxy :data_bag_item, 'Resource::DataBagItem' |
#data_bags ⇒ Class<Resource::DataBag>
Get the list of data_bags for this ChefAPI::Connection. This method is threadsafe.
42 |
# File 'lib/chef-api/connection.rb', line 42 proxy :data_bags, 'Resource::DataBag' |
#delete(path, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP DELETE request
170 171 172 |
# File 'lib/chef-api/connection.rb', line 170 def delete(path, params = {}, = {}) request(:delete, path, params) end |
#environments ⇒ Class<Resource::Environment>
Get the list of environments for this ChefAPI::Connection. This method is threadsafe.
44 |
# File 'lib/chef-api/connection.rb', line 44 proxy :environments, 'Resource::Environment' |
#get(path, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP GET request
109 110 111 |
# File 'lib/chef-api/connection.rb', line 109 def get(path, params = {}, = {}) request(:get, path, params) end |
#groups ⇒ Class<Resource::Group>
Get the list of groups for this ChefAPI::Connection. This method is threadsafe.
45 |
# File 'lib/chef-api/connection.rb', line 45 proxy :groups, 'Resource::Group' |
#nodes ⇒ Class<Resource::Node>
Get the list of nodes for this ChefAPI::Connection. This method is threadsafe.
46 |
# File 'lib/chef-api/connection.rb', line 46 proxy :nodes, 'Resource::Node' |
#organizations ⇒ Class<Resource::Organization>
Get the list of organizations for this ChefAPI::Connection. This method is threadsafe.
52 |
# File 'lib/chef-api/connection.rb', line 52 proxy :organizations, 'Resource::Organization' |
#partial_search ⇒ Class<Resource::PartialSearch>
Get the list of partial_search for this ChefAPI::Connection. This method is threadsafe.
47 |
# File 'lib/chef-api/connection.rb', line 47 proxy :partial_search, 'Resource::PartialSearch' |
#patch(path, data, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP PATCH request
156 157 158 |
# File 'lib/chef-api/connection.rb', line 156 def patch(path, data, params = {}, = {}) request(:patch, path, data, params) end |
#post(path, data, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP POST request
126 127 128 |
# File 'lib/chef-api/connection.rb', line 126 def post(path, data, params = {}, = {}) request(:post, path, data, params) end |
#principals ⇒ Class<Resource::Principal>
Get the list of principals for this ChefAPI::Connection. This method is threadsafe.
48 |
# File 'lib/chef-api/connection.rb', line 48 proxy :principals, 'Resource::Principal' |
#put(path, data, params = {}, request_options = {}) ⇒ String, Hash
Make a HTTP PUT request
141 142 143 |
# File 'lib/chef-api/connection.rb', line 141 def put(path, data, params = {}, = {}) request(:put, path, data, params) end |
#request(verb, path, data = {}, params = {}, request_options = {}) ⇒ 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.
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 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/chef-api/connection.rb', line 200 def request(verb, path, data = {}, params = {}, = {}) log.info "#{verb.to_s.upcase} #{path}..." log.debug "Chef flavor: #{flavor.inspect}" # Build the URI and request object from the given information if [:delete, :get].include?(verb) uri = build_uri(verb, path, data) else uri = build_uri(verb, path, params) end 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) log.info "Detected file/io presence" request.body_stream = data elsif data.is_a?(Hash) # If any of the values in the hash are File-like, assume this is a # multi-part post if data.values.any? { |value| value.respond_to?(:read) } log.info "Detected multipart body" multipart = Multipart::Body.new(data) log.debug "Content-Type: #{multipart.content_type}" log.debug "Content-Length: #{multipart.content_length}" request.content_length = multipart.content_length request.content_type = multipart.content_type request.body_stream = multipart.stream else log.info "Detected form data" request.form_data = data end else log.info "Detected regular body" request.body = data end end # Sign the request if [:sign] == false log.info "Skipping signed header authentication (user requested)..." else add_signing_headers(verb, uri.path, request) end # 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) # Large or filtered result sets can take a long time to return, so allow # setting a longer read_timeout for our client if we want to make an # expensive request. connection.read_timeout = read_timeout if read_timeout # 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 " \ "damages 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) log.debug "Raw response:" log.debug response.body case response when Net::HTTPRedirection redirect = URI.parse(response['location']).to_s log.debug "Performing HTTP redirect to #{redirect}" request(verb, redirect, data) 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 |
#roles ⇒ Class<Resource::Role>
Get the list of roles for this ChefAPI::Connection. This method is threadsafe.
49 |
# File 'lib/chef-api/connection.rb', line 49 proxy :roles, 'Resource::Role' |
#same_options?(opts) ⇒ Boolean
Determine if the given options are the same as ours.
94 95 96 |
# File 'lib/chef-api/connection.rb', line 94 def (opts) opts.hash == .hash end |
#search ⇒ Class<Resource::Search>
Get the list of search for this ChefAPI::Connection. This method is threadsafe.
50 |
# File 'lib/chef-api/connection.rb', line 50 proxy :search, 'Resource::Search' |
#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.
378 379 380 381 382 |
# File 'lib/chef-api/connection.rb', line 378 def to_query_string(hash) hash.map do |key, value| "#{URI.escape(key.to_s)}=#{URI.escape(value.to_s)}" end.join('&')[/.+/] end |
#users ⇒ Class<Resource::User>
Get the list of users for this ChefAPI::Connection. This method is threadsafe.
51 |
# File 'lib/chef-api/connection.rb', line 51 proxy :users, 'Resource::User' |