Class: Chef::REST
- Inherits:
-
Object
- Object
- Chef::REST
- Defined in:
- lib/chef/rest.rb
Defined Under Namespace
Classes: CookieJar
Instance Attribute Summary collapse
-
#cookies ⇒ Object
Returns the value of attribute cookies.
-
#url ⇒ Object
Returns the value of attribute url.
Instance Method Summary collapse
-
#authenticate(user, pass) ⇒ Object
Authenticate.
- #create_url(path) ⇒ Object
-
#delete_rest(path) ⇒ Object
Send an HTTP DELETE request to the path.
-
#get_rest(path, raw = false) ⇒ Object
Send an HTTP GET request to the path.
-
#initialize(url) ⇒ REST
constructor
A new instance of REST.
-
#post_rest(path, json) ⇒ Object
Send an HTTP POST request to the path.
-
#put_rest(path, json) ⇒ Object
Send an HTTP PUT request to the path.
-
#register(user, pass, validation_token = nil) ⇒ Object
Register for an OpenID.
-
#run_request(method, url, data = false, limit = 10, raw = false) ⇒ Object
Actually run an HTTP request.
Constructor Details
Instance Attribute Details
#cookies ⇒ Object
Returns the value of attribute cookies.
35 36 37 |
# File 'lib/chef/rest.rb', line 35 def @cookies end |
#url ⇒ Object
Returns the value of attribute url.
35 36 37 |
# File 'lib/chef/rest.rb', line 35 def url @url end |
Instance Method Details
#authenticate(user, pass) ⇒ Object
Authenticate
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/chef/rest.rb', line 66 def authenticate(user, pass) Chef::Log.debug("Authenticating #{user} via openid") response = post_rest('openid/consumer/start', { "openid_identifier" => "#{Chef::Config[:openid_url]}/openid/server/node/#{user}", "submit" => "Verify" }) post_rest( "#{Chef::Config[:openid_url]}#{response["action"]}", { "password" => pass } ) end |
#create_url(path) ⇒ Object
103 104 105 106 107 108 109 |
# File 'lib/chef/rest.rb', line 103 def create_url(path) if path =~ /^(http|https):\/\// URI.parse(path) else URI.parse("#{@url}/#{path}") end end |
#delete_rest(path) ⇒ Object
Send an HTTP DELETE request to the path
89 90 91 |
# File 'lib/chef/rest.rb', line 89 def delete_rest(path) run_request(:DELETE, create_url(path)) end |
#get_rest(path, raw = false) ⇒ Object
Send an HTTP GET request to the path
Parameters
- path
-
The path to GET
- raw
-
Whether you want the raw body returned, or JSON inflated. Defaults
to JSON inflated.
84 85 86 |
# File 'lib/chef/rest.rb', line 84 def get_rest(path, raw=false) run_request(:GET, create_url(path), false, 10, raw) end |
#post_rest(path, json) ⇒ Object
Send an HTTP POST request to the path
94 95 96 |
# File 'lib/chef/rest.rb', line 94 def post_rest(path, json) run_request(:POST, create_url(path), json) end |
#put_rest(path, json) ⇒ Object
Send an HTTP PUT request to the path
99 100 101 |
# File 'lib/chef/rest.rb', line 99 def put_rest(path, json) run_request(:PUT, create_url(path), json) end |
#register(user, pass, validation_token = nil) ⇒ Object
Register for an OpenID
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/chef/rest.rb', line 43 def register(user, pass, validation_token=nil) Chef::Log.debug("Registering #{user} for an openid") registration = nil begin registration = get_rest("registrations/#{user}") rescue Net::HTTPServerException => e unless e. =~ /^404/ raise e end end unless registration post_rest( "registrations", { :id => user, :password => pass, :validation_token => validation_token } ) end end |
#run_request(method, url, data = false, limit = 10, raw = false) ⇒ Object
Actually run an HTTP request. First argument is the HTTP method, which should be one of :GET, :PUT, :POST or :DELETE. Next is the URL, then an object to include in the body (which will be converted with .to_json) and finally, the limit of HTTP Redirects to follow (10).
Typically, you won’t use this method – instead, you’ll use one of the helper methods (get_rest, post_rest, etc.)
Will return the body of the response on success.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 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 233 234 235 |
# File 'lib/chef/rest.rb', line 120 def run_request(method, url, data=false, limit=10, raw=false) http_retry_delay = Chef::Config[:http_retry_delay] http_retry_count = Chef::Config[:http_retry_count] raise ArgumentError, 'HTTP redirect too deep' if limit == 0 http = Net::HTTP.new(url.host, url.port) if url.scheme == "https" http.use_ssl = true if Chef::Config[:ssl_verify_mode] == :verify_none http.verify_mode = OpenSSL::SSL::VERIFY_NONE end if File.exists?(Chef::Config[:ssl_client_cert]) http.cert = OpenSSL::X509::Certificate.new(File.read(Chef::Config[:ssl_client_cert])) http.key = OpenSSL::PKey::RSA.new(File.read(Chef::Config[:ssl_client_key])) end end http.read_timeout = Chef::Config[:rest_timeout] headers = Hash.new unless raw headers = { 'Accept' => "application/json", } end if @cookies.has_key?("#{url.host}:#{url.port}") headers['Cookie'] = @cookies["#{url.host}:#{url.port}"] end req = nil case method when :GET req_path = "#{url.path}" req_path << "?#{url.query}" if url.query req = Net::HTTP::Get.new(req_path, headers) when :POST headers["Content-Type"] = 'application/json' if data req = Net::HTTP::Post.new(url.path, headers) req.body = data.to_json if data when :PUT headers["Content-Type"] = 'application/json' if data req = Net::HTTP::Put.new(url.path, headers) req.body = data.to_json if data when :DELETE req_path = "#{url.path}" req_path << "?#{url.query}" if url.query req = Net::HTTP::Delete.new(req_path, headers) else raise ArgumentError, "You must provide :GET, :PUT, :POST or :DELETE as the method" end # Optionally handle HTTP Basic Authentication req.basic_auth(url.user, url.password) if url.user Chef::Log.debug("Sending HTTP Request via #{req.method} to #{req.path}") res = nil tf = nil http_retries = 1 begin res = http.request(req) do |response| if raw tf = Tempfile.new("chef-rest") # Stolen from http://www.ruby-forum.com/topic/166423 # Kudos to _why! size, total = 0, response.header['Content-Length'].to_i response.read_body do |chunk| tf.write(chunk) size += chunk.size if size == 0 Chef::Log.debug("#{req.path} done (0 length file)") elsif total == 0 Chef::Log.debug("#{req.path} (zero content length)") else Chef::Log.debug("#{req.path}" + " %d%% done (%d of %d)" % [(size * 100) / total, size, total]) end end tf.close tf else response.read_body end response end rescue Errno::ECONNREFUSED Chef::Log.error("Connection refused connecting to #{url.host}:#{url.port} for #{req.path} #{http_retries}/#{http_retry_count}") sleep(http_retry_delay) retry if (http_retries += 1) < http_retry_count raise Errno::ECONNREFUSED, "Connection refused connecting to #{url.host}:#{url.port} for #{req.path}, giving up" rescue Timeout::Error Chef::Log.error("Timeout connecting to #{url.host}:#{url.port} for #{req.path}, retry #{http_retries}/#{http_retry_count}") sleep(http_retry_delay) retry if (http_retries += 1) < http_retry_count raise Timeout::Error, "Timeout connecting to #{url.host}:#{url.port} for #{req.path}, giving up" end if res.kind_of?(Net::HTTPSuccess) if res['set-cookie'] @cookies["#{url.host}:#{url.port}"] = res['set-cookie'] end if res['content-type'] =~ /json/ JSON.parse(res.body) else if raw tf else res.body end end elsif res.kind_of?(Net::HTTPFound) or res.kind_of?(Net::HTTPMovedPermanently) if res['set-cookie'] @cookies["#{url.host}:#{url.port}"] = res['set-cookie'] end run_request(:GET, create_url(res['location']), false, limit - 1, raw) else res.error! end end |