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::HTTPclass 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_bags ⇒ Class<Resource::DataBag>
Get the list of data_bags for this Connection.
-
#delete(path, params = {}) ⇒ String, Hash
Make a HTTP DELETE request.
-
#environments ⇒ Class<Resource::Environment>
Get the list of environments for this Connection.
-
#get(path, params = {}) ⇒ String, Hash
Make a HTTP GET request.
-
#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.
-
#patch(path, data) ⇒ String, Hash
Make a HTTP PATCH request.
-
#post(path, data) ⇒ String, Hash
Make a HTTP POST request.
-
#principals ⇒ Class<Resource::Principal>
Get the list of principals for this Connection.
-
#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.
-
#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.
-
#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.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/chef-api/connection.rb', line 69 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.
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 |
# File 'lib/chef-api/connection.rb', line 277 def build_uri(verb, path, params = {}) log.info "Building URI..." # Add any query string parameters if [:delete, :get].include?(verb) 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 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.
313 314 315 |
# File 'lib/chef-api/connection.rb', line 313 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_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 = {}) ⇒ String, Hash
Make a HTTP DELETE request
156 157 158 |
# File 'lib/chef-api/connection.rb', line 156 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.
43 |
# File 'lib/chef-api/connection.rb', line 43 proxy :environments, 'Resource::Environment' |
#get(path, params = {}) ⇒ String, Hash
Make a HTTP GET request
103 104 105 |
# File 'lib/chef-api/connection.rb', line 103 def get(path, params = {}) request(:get, path, params) end |
#nodes ⇒ Class<Resource::Node>
Get the list of nodes for this ChefAPI::Connection. This method is threadsafe.
44 |
# File 'lib/chef-api/connection.rb', line 44 proxy :nodes, 'Resource::Node' |
#patch(path, data) ⇒ String, Hash
Make a HTTP PATCH request
143 144 145 |
# File 'lib/chef-api/connection.rb', line 143 def patch(path, data) request(:patch, path, data) end |
#post(path, data) ⇒ String, Hash
Make a HTTP POST request
117 118 119 |
# File 'lib/chef-api/connection.rb', line 117 def post(path, data) request(:post, path, data) end |
#principals ⇒ Class<Resource::Principal>
Get the list of principals for this ChefAPI::Connection. This method is threadsafe.
45 |
# File 'lib/chef-api/connection.rb', line 45 proxy :principals, 'Resource::Principal' |
#put(path, data) ⇒ String, Hash
Make a HTTP PUT request
130 131 132 |
# File 'lib/chef-api/connection.rb', line 130 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.
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 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 |
# File 'lib/chef-api/connection.rb', line 179 def request(verb, path, data = {}) log.info "#{verb.to_s.upcase} #{path}..." log.debug "Chef flavor: #{flavor.inspect}" # 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) 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.
46 |
# File 'lib/chef-api/connection.rb', line 46 proxy :roles, 'Resource::Role' |
#same_options?(opts) ⇒ Boolean
Determine if the given options are the same as ours.
89 90 91 |
# File 'lib/chef-api/connection.rb', line 89 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.
327 328 329 330 331 |
# File 'lib/chef-api/connection.rb', line 327 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.
47 |
# File 'lib/chef-api/connection.rb', line 47 proxy :users, 'Resource::User' |