Class: Etcd::Client

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Keys, Mod::Leader, Mod::Lock, Stats
Defined in:
lib/etcd/client.rb

Overview

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

Defined Under Namespace

Classes: Config

Constant Summary collapse

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 }

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mod::Leader

#delete_leader, #get_leader, #mod_leader_endpoint, #set_leader

Methods included from Mod::Lock

#acquire_lock, #delete_lock, #get_lock, #lock, #mod_lock_endpoint, #renew_lock

Methods included from Keys

#compare_and_swap, #create, #create_in_order, #delete, #eternal_watch, #exists?, #get, #key_endpoint, #set, #update, #watch

Methods included from Stats

#stats, #stats_endpoint

Constructor Details

#initialize(opts = {}) {|@config| ... } ⇒ Client

Creates an Etcd::Client object. It accepts a hash opts as argument

rubocop:disable CyclomaticComplexity

Parameters:

  • opts (Hash) (defaults to: {})

    The options for new Etcd::Client object

Yields:



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/etcd/client.rb', line 50

def initialize(opts = {})
  @host = opts[:host] || '127.0.0.1'
  @port = opts[:port] || 4001
  @config = Config.new
  @config.read_timeout = opts[:read_timeout] || 60
  @config.allow_redirect = opts.key?(:allow_redirect) ? opts[:allow_redirect] : true
  @config.use_ssl = opts[:use_ssl] || false
  @config.verify_mode = opts.key?(:verify_mode) ? opts[:verify_mode] : OpenSSL::SSL::VERIFY_PEER
  @config.user_name = opts[:user_name] || nil
  @config.password = opts[:password] || nil
  @config.allow_redirect = opts.key?(:allow_redirect) ? opts[:allow_redirect] : true
  yield @config if block_given?
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



40
41
42
# File 'lib/etcd/client.rb', line 40

def config
  @config
end

#hostObject (readonly)

Returns the value of attribute host.



40
41
42
# File 'lib/etcd/client.rb', line 40

def host
  @host
end

#httpObject (readonly)

Returns the value of attribute http.



40
41
42
# File 'lib/etcd/client.rb', line 40

def http
  @http
end

#portObject (readonly)

Returns the value of attribute port.



40
41
42
# File 'lib/etcd/client.rb', line 40

def port
  @port
end

Instance Method Details

#api_execute(path, method, options = {}) ⇒ Object

This method sends api request to etcd server.

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



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/etcd/client.rb', line 92

def api_execute(path, method, options = {})
  params = options[:params]
  case  method
  when :get
    req = build_http_request(Net::HTTP::Get, path, params)
  when :post
    req = build_http_request(Net::HTTP::Post, path, nil, params)
  when :put
    req = build_http_request(Net::HTTP::Put, path, nil, params)
  when :delete
    req = build_http_request(Net::HTTP::Delete, path, params)
  else
    fail "Unknown http action: #{method}"
  end
  timeout = options[:timeout] || @read_timeout
  http = Net::HTTP.new(host, port)
  http.read_timeout = timeout
  setup_https(http)
  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, req, params)
end

#build_http_request(klass, path, params = nil, body = nil) ⇒ Object

rubocop:enable MethodLength



161
162
163
164
165
166
167
# File 'lib/etcd/client.rb', line 161

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?
  Etcd::Log.debug("Built #{klass} path:'#{path}'  body:'#{req.body}'")
  req
end

#leaderObject

Get the current leader



81
82
83
# File 'lib/etcd/client.rb', line 81

def leader
  api_execute(version_prefix + '/leader', :get).body.strip
end

#machinesObject

Returns array of all machines in the cluster



76
77
78
# File 'lib/etcd/client.rb', line 76

def machines
  api_execute(version_prefix + '/machines', :get).body.split(',').map(&:strip)
end

#process_http_request(res, req = nil, params = nil) ⇒ Object

need to ahve original request to process the response when it redirects



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/etcd/client.rb', line 135

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
      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
    fail Error.from_http_response(res)
  else
    Log.debug('Http error')
    Log.debug(res.body)
    res.error!
  end
end

#setup_https(http) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/etcd/client.rb', line 117

def setup_https(http)
  http.use_ssl = use_ssl
  http.verify_mode = verify_mode
  unless config.ssl_cert.nil?
    Log.debug('Setting up ssl cert')
    http.cert = config.ssl_cert
  end
  unless config.ssl_key.nil?
    Log.debug('Setting up ssl key')
    http.key = config.ssl_key
  end
  unless config.ca_file.nil?
    Log.debug('Setting up ssl ca file to :' + config.ca_file)
    http.ca_file = config.ca_file
  end
end

#versionObject

Returns the etcd daemon version



71
72
73
# File 'lib/etcd/client.rb', line 71

def version
  api_execute('/version', :get).body
end

#version_prefixObject

Returns the etcd api version that will be used for across API methods



66
67
68
# File 'lib/etcd/client.rb', line 66

def version_prefix
  '/v2'
end