Class: Etcd::Client

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Keys, 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 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:



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/etcd/client.rb', line 46

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.



36
37
38
# File 'lib/etcd/client.rb', line 36

def config
  @config
end

#hostObject (readonly)

Returns the value of attribute host.



36
37
38
# File 'lib/etcd/client.rb', line 36

def host
  @host
end

#httpObject (readonly)

Returns the value of attribute http.



36
37
38
# File 'lib/etcd/client.rb', line 36

def http
  @http
end

#portObject (readonly)

Returns the value of attribute port.



36
37
38
# File 'lib/etcd/client.rb', line 36

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



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/etcd/client.rb', line 88

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



157
158
159
160
161
162
163
# File 'lib/etcd/client.rb', line 157

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



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

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

#machinesObject

Returns array of all machines in the cluster



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

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



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/etcd/client.rb', line 131

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



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/etcd/client.rb', line 113

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



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

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

#version_prefixObject

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



62
63
64
# File 'lib/etcd/client.rb', line 62

def version_prefix
  '/v2'
end