diff options
Diffstat (limited to 'lib/chef/rest.rb')
-rw-r--r-- | lib/chef/rest.rb | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/lib/chef/rest.rb b/lib/chef/rest.rb index 1ca18e4ef5..f71c203b3a 100644 --- a/lib/chef/rest.rb +++ b/lib/chef/rest.rb @@ -26,7 +26,104 @@ require 'json' class Chef class REST - def initialize(url, username) + def initialize(url) + @url = url + @cookies = Hash.new + end + + # Send an HTTP GET request to the path + def get_rest(path) + run_request(:GET, create_url(path)) + end + + # Send an HTTP DELETE request to the path + def delete_rest(path) + run_request(:DELETE, create_url(path)) + end + + # Send an HTTP POST request to the path + def post_rest(path, json) + run_request(:POST, create_url(path), json) + end + + # Send an HTTP PUT request to the path + def put_rest(path, json) + run_request(:PUT, create_url(path), json) + end + + def create_url(path) + if path =~ /^(http|https):\/\// + URI.parse(path) + else + URI.parse("#{@url}/#{path}") + end + end + + # 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. + def run_request(method, url, data=false, limit=10) + 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 + end + http.read_timeout = Chef::Config[:rest_timeout] + headers = { + 'Accept' => "application/json", + } + if @cookies["#{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 + res = http.request(req) + if res.kind_of?(Net::HTTPSuccess) + if res['set-cookie'] + @cookies["#{url.host}:#{url.port}"] = res['set-cookie'] + end + if res['content-type'] == "application/json" + JSON.parse(res.body) + else + res.body + end + elsif res.kind_of?(Net::HTTPRedirection) + if res['set-cookie'] + @cookies["#{url.host}:#{url.port}"] = res['set-cookie'] + end + run_request(:GET, create_url(res['location']), false, limit - 1) + else + res.error! + end end end |