Class: CMDB::Source::Consul

Inherits:
Network show all
Defined in:
lib/cmdb/source/consul.rb

Constant Summary collapse

ARRAY_VALUE =

Regular expression to match array values

/^\[(.*)\]$/

Instance Attribute Summary

Attributes inherited from Network

#http_url

Attributes inherited from CMDB::Source

#prefix, #uri

Instance Method Summary collapse

Methods inherited from CMDB::Source

create, detect

Constructor Details

#initialize(uri, prefix) ⇒ Consul

Returns a new instance of Consul.



11
12
13
14
15
16
# File 'lib/cmdb/source/consul.rb', line 11

def initialize(uri, prefix)
  super(uri, 8500, prefix)
  useless = uri.path.split('/')
  useless.shift ; useless.pop # del initial "" and final word (aka prefix)
  @useless = CMDB.join(useless)
end

Instance Method Details

#each_pair(&_block) ⇒ Integer

Iterate through all keys in this source.

Returns:

  • (Integer)

    number of key/value pairs that were yielded



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/cmdb/source/consul.rb', line 66

def each_pair(&_block)
  path = path_to('/')

  case result = http_get(path, query:'recurse')
  when String
    result = json_parse(result)
  when 404
    return # no keys!
  end

  unless result.is_a?(Array)
    raise CMDB::Error.new("Consul 'GET #{path}': expected Array, got #{all.class.name}")
  end

  result.each do |item|
    key = slash_to_dot(item['Key'])
    key.sub(@useless,'')
    next unless item['Value']
    value = json_parse(Base64.decode64(item['Value']))
    validate!(key, value)
    yield(key, value)
  end

  result.size
end

#get(key) ⇒ Object

Get a single key from consul. If the key is not found, return nil.

Parameters:

  • key (String)

    dot-notation key

Returns:

  • (Object)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/cmdb/source/consul.rb', line 22

def get(key)
  return nil unless prefixed?(key)
  key = dot_to_slash(key)
  response = http_get path_to(key)
  case response
  when String
    response = json_parse(response)
    item = response.first
    item['Value'] && value = json_parse(Base64.decode64(item['Value']))
    validate!(key, value)
  when 404
    nil
  else
    raise CMDB::Error.new("Unexpected consul response #{response.inspect}")
  end
end

#path_to(subpath) ⇒ Object

Given a key’s relative path, return its absolute REST path in the consul kv, including the ‘/v1/kv/` prefix and any subkey path specified at initialize time.

Parameters:

  • subpath (String)

    key path relative to base



106
107
108
# File 'lib/cmdb/source/consul.rb', line 106

def path_to(subpath)
  ::File.join('/v1/kv/', @uri.path, subpath)
end

#pingBoolean

Test connectivity to consul agent.

Returns:

  • (Boolean)


95
96
97
98
99
# File 'lib/cmdb/source/consul.rb', line 95

def ping
  http_get('/') == 'Consul Agent'
rescue
  false
end

#set(key, value) ⇒ true?

Set a single key in consul. If value is nil, then delete the key entirely from consul. If this source cannot accept the write due to key name limitations, return nil.

Parameters:

  • key (String)

    dot-notation key

  • value (Object)

    new value of key

Returns:

  • (true, nil)

Raises:

  • (CMDB:Error)

    if the write fails atthe consul server



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/cmdb/source/consul.rb', line 47

def set(key, value)
  return nil unless prefixed?(key)
  key = dot_to_slash(key)
  if value.nil?
    status = http_delete path_to(key)
  else
    validate!(key, value)
    status = http_put path_to(key), value
  end

  if status >= 200 && status < 300
    true
  else
    raise CMDB::Error.new("Consul put/delete failed with status #{status}")
  end
end

#slash_to_dot(path) ⇒ Object

Transform a subpath into a key name. Account for base-path prefix if necessary.



112
113
114
115
116
117
# File 'lib/cmdb/source/consul.rb', line 112

def slash_to_dot(path)
  dot = super
  dot.sub!(@useless,'')
  dot=dot[1..-1] if dot[0] == '.'
  dot
end