Class: Etcd::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/etcd-tools/mixins/etcd.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Client.

Yields:

  • (@config)


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/etcd-tools/mixins/etcd.rb', line 12

def initialize(opts = {})
  @cluster = opts[:cluster] || [{ host: '127.0.0.1', port: 2379 }]
  if !opts[:host].nil? || !opts[:port].nil?
    @cluster = [{ host: opts[:host], port: opts[:port] }]
  end
  @config = Config.new
  @config.read_timeout = opts[:read_timeout] || 10
  @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.ca_file = opts.key?(:ca_file) ? opts[:ca_file] : nil
  @config.ssl_cert = opts.key?(:ssl_cert) ? opts[:ssl_cert] : nil
  @config.ssl_key = opts.key?(:ssl_key) ? opts[:ssl_key] : nil
  yield @config if block_given?
end

Instance Attribute Details

#clusterObject (readonly)

Returns the value of attribute cluster.



10
11
12
# File 'lib/etcd-tools/mixins/etcd.rb', line 10

def cluster
  @cluster
end

Instance Method Details

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



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/etcd-tools/mixins/etcd.rb', line 29

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
  req.basic_auth(user_name, password) if [user_name, password].all?
  cluster_http_request(req, options)
end

#build_http_object(host, port, options = {}) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/etcd-tools/mixins/etcd.rb', line 74

def build_http_object(host, port, options={})
  http = Net::HTTP.new(host, port)
  http.read_timeout = options[:timeout] || read_timeout
  http.open_timeout = options[:timeout] || read_timeout # <- can't modify Config constant with specific option
  setup_https(http)
  http
end

#cluster_http_request(req, options = {}) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/etcd-tools/mixins/etcd.rb', line 47

def cluster_http_request(req, options={})
  errs = []
  cluster.each do |member|
    http = build_http_object(member[:host], member[:port], options)
    begin
      Log.debug("Invoking: '#{req.class}' against '#{member[:host]}:#{member[:port]}' -> '#{req.path}'")
      res = http.request(req)
      Log.debug("Response code: #{res.code}")
      Log.debug("Response body: #{res.body}")
      return process_http_request(res)
    rescue Timeout::Error => e
      Log.debug("Connection timed out on #{member[:host]}:#{member[:host]}")
      errs << e
      next
    rescue Errno::ECONNRESET => e
      Log.debug("Connection reset on #{member[:host]}:#{member[:host]}")
      errs << e
      next
    rescue Errno::ECONNREFUSED => e
      Log.debug("Connection refused on #{member[:host]}:#{member[:host]}")
      errs << e
      next
    end
  end
  fail(Etcd::ClusterConnectError, "Couldn't connect to the ETCD cluster: #{errs.map(&:class).map(&:to_s)}")
end

#get_hash(path = '') ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/etcd-tools/mixins/etcd.rb', line 98

def get_hash(path = '')
  h = {}
  get(path).children.each do |child|
    if get(child.key).directory?
      h[child.key.split('/').last.to_s] = get_hash child.key
    else
      value = JSON.parse(child.value) rescue value = child.value
      h[child.key.split('/').last.to_s] = value
    end
  end
  return Hash[h.sort]
rescue Exception => e
  raise e
  puts e.backtrace
end

#healthy?Boolean

Returns:

  • (Boolean)


119
120
121
122
123
# File 'lib/etcd-tools/mixins/etcd.rb', line 119

def healthy?
  JSON.parse(api_execute('/health', :get).body)['health'] == 'true'
rescue
  false
end

#membersObject



114
115
116
117
# File 'lib/etcd-tools/mixins/etcd.rb', line 114

def members
  members = JSON.parse(api_execute(version_prefix + '/members', :get).body)['members']
  Hash[members.map{|member| [ member['id'], member.tap { |h| h.delete('id') }]}]
end

#set_hash(hash, path = '') ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/etcd-tools/mixins/etcd.rb', line 82

def set_hash(hash, path = '')
  hash.each do |key, value|
    path = "" if path == '/'
    etcd_key = path + '/' + key.to_s
    if value.class == Hash
      set_hash(value, etcd_key)
    elsif value.class == Array
      set(etcd_key, value: value.to_json)
    else
      set(etcd_key, value: value)
    end
  end
rescue Exception => e
  raise e #fixme
end