Skip to content

Commit

Permalink
Added support for agent_members()
Browse files Browse the repository at this point in the history
  • Loading branch information
pierresouchay committed Feb 27, 2020
1 parent 6ac8c2e commit 1cd48d3
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## (UNRELEASED)

NEW FEATURES:

* Added support for `agent_members()` aka https://www.consul.io/api/agent.html#list-members

## 1.24.1 (February 19, 2020)

BUGFIX:
Expand Down
17 changes: 17 additions & 0 deletions TemplateAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,23 @@ value123 : <%= result.get_decoded('/my/multiple/values/value123') %>
Since `kv('/my/multiple/values', recurse: true)` will retrieve all values at once, it might be more
efficient in some cases than retrieving all values one by one.

## agent_members(wan: false)

[Get the Serf information](https://www.consul.io/api/agent.html#list-members) from Consul Agent perspective.
This is a list of Serf information containing serf information. This information is not consistent and should be used with care, most of the time, you should prefer `nodes()`.

The object do contains the following attributes (accessed as Hash elements):
* "Name": Name of node
* "Addr": IP Address of node as seen in serf
* "Port": Serf port
* "Tags": Hash of properties, including version, dc, VSN info...
* "Status": Serf code from 0 to 5 giving Health information

Another property is available as status, that translates the Hash property "Status" into something human redable ('none', 'alive', 'leaving', 'left', 'failed')

See [samples/members.json.erb](samples/members.json.erb) for example of usage.


## agent_metrics()

[Get the metrics of Consul Agent](https://www.consul.io/api/agent.html#view-metrics). Since this endpoint does
Expand Down
3 changes: 3 additions & 0 deletions bin/consul-templaterb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ options = {
'/v1/agent/metrics': {
min_duration: 60 # Refresh metrics only minute max
},
'/v1/agent/members': {
min_duration: 60 # Refresh self info every minute max
},
'/v1/agent/self': {
min_duration: 60 # Refresh self info every minute max
}
Expand Down
46 changes: 46 additions & 0 deletions lib/consul/async/consul_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ def agent_metrics
create_if_missing(path, query_params) { ConsulAgentMetrics.new(ConsulEndpoint.new(consul_conf, path, true, query_params, default_value)) }
end

# https://www.consul.io/api/agent.html#list-members
def agent_members(wan: false)
path = '/v1/agent/members'
query_params = {}
query_params['wan'] = true if wan
default_value = '[]'
create_if_missing(path, query_params) { ConsulTemplateMembers.new(ConsulEndpoint.new(consul_conf, path, true, query_params, default_value)) }
end

# Return a param of template
def param(key, default_value = nil)
v = @context[:params][key]
Expand Down Expand Up @@ -598,6 +607,43 @@ def initialize(consul_endpoint)
end
end

# The ServiceInstance has shortcuts (such as service_address method), but is
# basically a Hash.
class SerfMember < Hash
def initialize(obj)
merge!(obj)
end

# List the possible Serf statuses as text, indexed by self['Status']
def serf_statuses
%w[none alive leaving left failed].freeze
end

# Return status as text
def status
serf_statuses[self['Status']] || "unknownStatus:#{self['Status']}"
end
end

# List of serf members of the whole cluster
class ConsulTemplateMembers < ConsulTemplateAbstractArray
def initialize(consul_endpoint)
super(consul_endpoint)
end

def result_delegate
return @cached_result if @cached_json == result.json

new_res = []
result.json.each do |v|
new_res << SerfMember.new(v)
end
@cached_result = new_res
@cached_json = result.json
new_res
end
end

# Key/Values representations
# This is an array as it might contain several values
# Several helpers exist to handle nicely transformations
Expand Down
3 changes: 2 additions & 1 deletion spec/consul/async/async_mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def mock_vault

def mock_consul
results = {}
%w[v1/agent/metrics
%w[v1/agent/members
v1/agent/metrics
v1/agent/self
v1/catalog/datacenters
v1/catalog/nodes
Expand Down
48 changes: 48 additions & 0 deletions spec/consul/async/resources/consul/v1/agent/members.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[
{
"Name": "tableaunode005-par",
"Addr": "10.236.127.20",
"Port": 8301,
"Tags": {
"acls": "1",
"build": "1.5.1criteoB:",
"dc": "par",
"id": "c3704306-a271-c212-16dd-a7d42c8e22bb",
"role": "node",
"segment": "",
"vsn": "2",
"vsn_max": "3",
"vsn_min": "2"
},
"Status": 1,
"ProtocolMin": 1,
"ProtocolMax": 5,
"ProtocolCur": 2,
"DelegateMin": 2,
"DelegateMax": 5,
"DelegateCur": 4
},
{
"Name": "kubes02e171-par",
"Addr": "10.236.134.42",
"Port": 8301,
"Tags": {
"acls": "1",
"build": "1.5.1criteoB:",
"dc": "par",
"id": "2d89527d-9a7d-057e-e301-296423cd04ea",
"role": "node",
"segment": "",
"vsn": "2",
"vsn_max": "3",
"vsn_min": "2"
},
"Status": 4,
"ProtocolMin": 1,
"ProtocolMax": 5,
"ProtocolCur": 2,
"DelegateMin": 2,
"DelegateMax": 5,
"DelegateCur": 4
}
]
3 changes: 3 additions & 0 deletions spec/consul/async/resources/templates/unit_members.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= agent_members.map do |a|
"#{a['Name']}/#{a['Addr']}/#{a.status}/#{a['Status']}"
end.join("\n") %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tableaunode005-par/10.236.127.20/alive/1
kubes02e171-par/10.236.134.42/failed/4

0 comments on commit 1cd48d3

Please sign in to comment.