Class: Etcd::Client

Inherits:
Object
  • Object
show all
Includes:
Helpers, Lockable
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

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Lockable

#lock

Methods included from Helpers

#eternal_watch, #has_key?

Constructor Details

#initialize(opts = {}) ⇒ Client

Creates a new instance of Etcd::Client. It accepts a hash opts as argument

Parameters:

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

    The options for new Etcd::Client object



30
31
32
33
34
35
36
37
# File 'lib/etcd/client.rb', line 30

def initialize(opts={})
  @host = opts[:host] || '127.0.0.1'
  @port = opts[:port] || 4001
  @read_timeout = opts[:read_timeout] || 60
  @allow_redirect = opts.has_key?(:allow_redirect) ? opts[:allow_redirect] : true
  @use_ssl = opts[:use_ssl] || false
  @verify_mode = opts[:verify_mode] || OpenSSL::SSL::VERIFY_PEER
end

Instance Attribute Details

#allow_redirectObject (readonly)

Returns the value of attribute allow_redirect.



20
21
22
# File 'lib/etcd/client.rb', line 20

def allow_redirect
  @allow_redirect
end

#hostObject (readonly)

Returns the value of attribute host.



20
21
22
# File 'lib/etcd/client.rb', line 20

def host
  @host
end

#httpObject (readonly)

Returns the value of attribute http.



20
21
22
# File 'lib/etcd/client.rb', line 20

def http
  @http
end

#portObject (readonly)

Returns the value of attribute port.



20
21
22
# File 'lib/etcd/client.rb', line 20

def port
  @port
end

#use_sslObject (readonly)

Returns the value of attribute use_ssl.



20
21
22
# File 'lib/etcd/client.rb', line 20

def use_ssl
  @use_ssl
end

#verify_modeObject (readonly)

Returns the value of attribute verify_mode.



20
21
22
# File 'lib/etcd/client.rb', line 20

def verify_mode
  @verify_mode
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)



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
# File 'lib/etcd/client.rb', line 152

def api_execute(path, method, options={})

  params = options[:params]
  timeout = options[:timeout] || @read_timeout

  http = if path=~/^http/
            uri = URI.parse(path)
            path =  uri.path
            Net::HTTP.new(uri.host, uri.port)
          else
            Net::HTTP.new(host, port)
          end
  http.read_timeout = timeout
  http.use_ssl = use_ssl
  http.verify_mode = verify_mode

  case  method
  when :get
    unless params.nil?
      encoded_params = URI.encode_www_form(params)
      path+= "?" + encoded_params
    end
    req = Net::HTTP::Get.new(path)
  when :post
    encoded_params = URI.encode_www_form(params)
    req = Net::HTTP::Post.new(path)
    req.body= encoded_params
    Log.debug("Setting body for post '#{encoded_params}'")
  when :put
    encoded_params = URI.encode_www_form(params)
    req = Net::HTTP::Put.new(path)
    req.body= encoded_params
    Log.debug("Setting body for put '#{encoded_params}'")
  when :delete
    unless params.nil?
      encoded_params = URI.encode_www_form(params)
      path+= "?" + encoded_params
    end
    req = Net::HTTP::Delete.new(path)
  else
    raise "Unknown http action: #{method}"
  end

  Log.debug("Invoking: '#{req.class}' against '#{path}")
  res = http.request(req)
  Log.debug("Response code: #{res.code}")
  if res.is_a?(Net::HTTPSuccess)
    Log.debug("Http success")
    res.body
  elsif redirect?(res.code.to_i) and allow_redirect
    Log.debug("Http redirect, following")
    api_execute(res['location'], method, params: params)
  else
    Log.debug("Http error")
    Log.debug(res.body)
    res.error!
  end
end

#create(key, value, ttl = nil) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/etcd/client.rb', line 80

def create(key, value, ttl = nil)
  path  = key_endpoint + key
  payload = {value: value, prevExist: false }
  payload['ttl'] = ttl unless ttl.nil?
  response = api_execute(path, :put, params: payload)
  json2obj(response)
end

#delete(key, opts = {}) ⇒ Object

Deletes a key along with all associated data

This method has following parameters as argument

  • key - key to be deleted



114
115
116
117
# File 'lib/etcd/client.rb', line 114

def delete(key,opts={})
  response = api_execute(key_endpoint + key, :delete, params:opts)
  json2obj(response)
end

#get(key, opts = {}) ⇒ Object

Retrives a key with its associated data, if key is not present it will return with message “Key Not Found”

This method has following parameters as argument

  • key - whose data to be retrive



123
124
125
126
# File 'lib/etcd/client.rb', line 123

def get(key, opts={})
  response = api_execute(key_endpoint + key, :get, params:opts)
  json2obj(response)
end

#key_endpointObject

Lists all the data (keys, dir etc) present in etcd store



55
56
57
# File 'lib/etcd/client.rb', line 55

def key_endpoint
  version_prefix + '/keys'
end

#leaderObject

Get the current leader in a cluster



50
51
52
# File 'lib/etcd/client.rb', line 50

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

#machinesObject

Lists all machines in the cluster



45
46
47
# File 'lib/etcd/client.rb', line 45

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

#set(key, value, ttl = nil) ⇒ Object

Adds a new key with specified value and ttl, overwrites old values if exists

This method has following parameters as argument

  • key - whose value to be set

  • value - value to be set for specified key

  • ttl - shelf life of a key (in secsonds) (optional)



102
103
104
105
106
107
108
# File 'lib/etcd/client.rb', line 102

def set(key, value, ttl=nil)
  path  = key_endpoint + key
  payload = {'value' => value}
  payload['ttl'] = ttl unless ttl.nil?
  response = api_execute(path, :put, params: payload)
  json2obj(response)
end

#test_and_set(key, value, prevValue, ttl = nil) ⇒ Object

Set a new value for key if previous value of key is matched

This method takes following parameters as argument

  • key - whose value is going to change if previous value is matched

  • value - new value to be set for specified key

  • prevValue - value of a key to compare with existing value of key

  • ttl - shelf life of a key (in secsonds) (optional)



71
72
73
74
75
76
77
# File 'lib/etcd/client.rb', line 71

def test_and_set(key, value, prevValue, ttl = nil)
  path  = key_endpoint + key
  payload = {'value' => value, 'prevValue' => prevValue }
  payload['ttl'] = ttl unless ttl.nil?
  response = api_execute(path, :put, params: payload)
  json2obj(response)
end

#update(key, value, ttl = nil) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/etcd/client.rb', line 88

def update(key, value, ttl = nil)
  path  = key_endpoint + key
  payload = {value: value, prevExist: true }
  payload['ttl'] = ttl unless ttl.nil?
  response = api_execute(path, :put, params: payload)
  json2obj(response)
end

#version_prefixObject

Currently use ‘v2’ as version for etcd store



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

def version_prefix
  '/v2'
end

#watch(key, options = {}) ⇒ Object

Gives a notification when specified key changes

This method has following parameters as argument @ key - key to be watched



135
136
137
138
139
140
141
142
143
144
# File 'lib/etcd/client.rb', line 135

def watch(key, options={})
  timeout = options[:timeout] || @read_timeout
  index = options[:waitIndex] || options[:index]
  response = if index.nil?
                api_execute(key_endpoint + key, :get, timeout: timeout, params:{wait: true})
              else
                api_execute(key_endpoint + key, :get, timeout: timeout, params: {wait: true, waitIndex: index})
              end
  json2obj(response)
end

#watch_endpointObject

Watches all keys and notifies if anyone changes



60
61
62
# File 'lib/etcd/client.rb', line 60

def watch_endpoint
  version_prefix + '/watch'
end