lib/etcd/client.rb in etcd-0.2.0.alpha vs lib/etcd/client.rb in etcd-0.2.0.beta.1

- old
+ new

@@ -1,7 +1,8 @@ # Encoding: utf-8 +require 'openssl' require 'net/http' require 'json' require 'etcd/log' require 'etcd/stats' require 'etcd/keys' @@ -14,38 +15,42 @@ # This is the central ruby class for Etcd. It provides methods for all # etcd api calls. It also provides few additional methods beyond the core # etcd api, like Etcd::Client#lock and Etcd::Client#eternal_watch, they # are defined in separate modules and included in this class class Client + HTTP_REDIRECT = ->(r) { r.is_a? Net::HTTPRedirection } + HTTP_SUCCESS = ->(r) { r.is_a? Net::HTTPSuccess } + HTTP_CLIENT_ERROR = ->(r) { r.is_a? Net::HTTPClientError } - HTTP_REDIRECT = ->(r){ r.is_a? Net::HTTPRedirection } - HTTP_SUCCESS = ->(r){ r.is_a? Net::HTTPSuccess } - HTTP_CLIENT_ERROR = ->(r){ r.is_a? Net::HTTPClientError } - include Stats include Keys include Mod::Lock include Mod::Leader attr_reader :host, :port, :http, :allow_redirect attr_reader :use_ssl, :verify_mode, :read_timeout + attr_reader :user_name, :password ## # Creates an Etcd::Client object. It accepts a hash +opts+ as argument # # @param [Hash] opts The options for new Etcd::Client object # @opts [String] :host IP address of the etcd server (default 127.0.0.1) # @opts [Fixnum] :port Port number of the etcd server (default 4001) # @opts [Fixnum] :read_timeout set HTTP read timeouts (default 60) + # rubocop:disable CyclomaticComplexity def initialize(opts = {}) @host = opts[:host] || '127.0.0.1' @port = opts[:port] || 4001 @read_timeout = opts[:read_timeout] || 60 @allow_redirect = opts.key?(:allow_redirect) ? opts[:allow_redirect] : true @use_ssl = opts[:use_ssl] || false @verify_mode = opts.key?(:verify_mode) ? opts[:verify_mode] : OpenSSL::SSL::VERIFY_PEER + @user_name = opts[:user_name] || nil + @password = opts[:password] || nil end + # rubocop:enable CyclomaticComplexity # Returns the etcd api version that will be used for across API methods def version_prefix '/v2' end @@ -69,10 +74,11 @@ # # This method has following parameters as argument # * path - etcd server path (etcd server end point) # * method - the request method used # * options - any additional parameters used by request method (optional) + # rubocop:disable MethodLength, CyclomaticComplexity def api_execute(path, method, options = {}) params = options[:params] case method when :get req = build_http_request(Net::HTTP::Get, path, params) @@ -88,25 +94,30 @@ timeout = options[:timeout] || @read_timeout http = Net::HTTP.new(host, port) http.read_timeout = timeout http.use_ssl = use_ssl http.verify_mode = verify_mode + req.basic_auth(user_name, password) if [user_name, password].all? Log.debug("Invoking: '#{req.class}' against '#{path}") res = http.request(req) Log.debug("Response code: #{res.code}") - process_http_request(res) + process_http_request(res, req, params) end - def process_http_request(res) + # need to ahve original request to process the response when it redirects + def process_http_request(res, req = nil, params = nil) case res when HTTP_SUCCESS Log.debug('Http success') res when HTTP_REDIRECT if allow_redirect - Log.debug('Http redirect, following') - api_execute(res['location'], method, params: params) + uri = URI(res['location']) + @host = uri.host + @port = uri.port + Log.debug("Http redirect, setting new host to: #{@host}:#{@port}, and retrying") + api_execute(uri.path, req.method.downcase.to_sym, params: params) else Log.debug('Http redirect not allowed') res.error! end when HTTP_CLIENT_ERROR @@ -115,9 +126,10 @@ Log.debug('Http error') Log.debug(res.body) res.error! end end + # rubocop:enable MethodLength def build_http_request(klass, path, params = nil, body = nil) path += '?' + URI.encode_www_form(params) unless params.nil? req = klass.new(path) req.body = URI.encode_www_form(body) unless body.nil?