consul-templaterb 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/TemplateAPI.md +3 -0
- data/lib/consul/async/consul_template.rb +25 -0
- data/lib/consul/async/version.rb +1 -1
- data/samples/consul-ui/README.md +43 -0
- data/samples/consul-ui/consul_template.json.erb +8 -7
- data/samples/consul-ui/js/service.js +1 -1
- data/samples/consul_template.html.erb +1 -1
- data/samples/consul_template.json.erb +1 -1
- data/samples/consul_template.xml.erb +1 -1
- data/samples/criteo/haproxy.cfg.erb +1 -1
- data/samples/criteo_choregraphies.txt.erb +49 -0
- data/samples/ha_proxy.cfg.erb +1 -1
- data/samples/nodes.html.erb +1 -1
- data/samples/services.html.erb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74b7cce156473c1c3cba5d028f352aef6a9463fc24b328f51585cd80c2b42e0d
|
4
|
+
data.tar.gz: 6fb08ec94eddac3b5e051359039ce1ec0a87593ecb32a91ab8b3b38fbf5f687f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a0ce21b647df4eaf71b3d1a6b5c791213cc5b9e0e224719aa27c49522e8a462f1a2ebfdc714af9ebd5d0d134d30662d1893c9dd7dd109a4fb1cabbde630a039
|
7
|
+
data.tar.gz: cad4a025f9df51b3f4544efd1a560d64b226f334056e5015e4aea5c9b38eb87d9a1265a5a755dacd1f902a338ef27a3441b472e68d672da29ea641b0ad81c2ee
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,14 @@
|
|
4
4
|
|
5
5
|
IMPROVEMENTS:
|
6
6
|
|
7
|
+
## 1.2.0 (May 17, 2018)
|
8
|
+
|
9
|
+
IMPROVEMENTS:
|
10
|
+
|
11
|
+
* Added snode.service_address to get the IP address of a service easily
|
12
|
+
without any logic in ERB files
|
13
|
+
* Improved consul-ui, added a [README.md](samples/consul-ui/README.md)
|
14
|
+
|
7
15
|
## 1.1.3 (May 17, 2018)
|
8
16
|
|
9
17
|
IMPROVEMENTS:
|
data/TemplateAPI.md
CHANGED
@@ -97,6 +97,9 @@ Full example: [samples/consul_template.txt.erb](samples/consul_template.txt.erb)
|
|
97
97
|
optional tag. If no tag is specified, will return all instances of service. By default, it will return all the
|
98
98
|
services that are passing or not. An optional argument passing might be used to retrieve only passing instances.
|
99
99
|
|
100
|
+
This object also contains a Helper to get easily the correct Address by using `service_address` which returns
|
101
|
+
the optional `['Service']['Address']` if found or `['Node']['Address']` otherwise.
|
102
|
+
|
100
103
|
<details><summary>Examples</summary>
|
101
104
|
<div class="samples">
|
102
105
|
|
@@ -269,9 +269,34 @@ module Consul
|
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
272
|
+
class ServiceInstance < Hash
|
273
|
+
def initialize(obj)
|
274
|
+
merge!(obj)
|
275
|
+
end
|
276
|
+
|
277
|
+
# Return ['Service']['Address'] if defined, the address of node otherwise
|
278
|
+
def service_address
|
279
|
+
val = self['Service']['Address']
|
280
|
+
val = self['Node']['Address'] unless !val.nil? && val != ''
|
281
|
+
val
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
272
285
|
class ConsulTemplateService < ConsulTemplateAbstractMap
|
273
286
|
def initialize(consul_endpoint)
|
274
287
|
super(consul_endpoint)
|
288
|
+
@cached_result = []
|
289
|
+
@cached_json = nil
|
290
|
+
end
|
291
|
+
|
292
|
+
def result_delegate
|
293
|
+
return @cached_result if @cached_json == result.json
|
294
|
+
new_res = []
|
295
|
+
result.json.each do |v|
|
296
|
+
new_res << ServiceInstance.new(v)
|
297
|
+
end
|
298
|
+
@cached_result = new_res
|
299
|
+
new_res
|
275
300
|
end
|
276
301
|
end
|
277
302
|
|
data/lib/consul/async/version.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
# consul-ui
|
2
|
+
|
3
|
+
A simple HTML5 app that displays all services within Consul with AJAX requests.
|
4
|
+
It supports fitering based on tags and does not rely on Consul to display pages,
|
5
|
+
meaning that it can be scaled horizontally without any troubles with Consul.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
```shell
|
10
|
+
consul-templaterb -c http://localhost:8500 samples/consul-ui/*.erb
|
11
|
+
```
|
12
|
+
|
13
|
+
Where `http://localhost:8500` is the address of the Consul agent you want to use to
|
14
|
+
perform requests.
|
15
|
+
|
16
|
+
The content is statically created, so you can serve it using any HTTP server very easily.
|
17
|
+
|
18
|
+
For development, you might use `python -m SimpleHTTPServer` in order to server the result
|
19
|
+
on your browser.
|
20
|
+
|
21
|
+
### Generating index.html
|
22
|
+
|
23
|
+
By default, the command `consul-templaterb -c http://localhost:8500 samples/consul-ui/*.erb``
|
24
|
+
will generate sample/consul-ui/consul-services-ui.html file. If you want to use index.html instead
|
25
|
+
you might use the `--template samples/consul-ui/consul-services-ui.html:samples/consul-ui/index.html`
|
26
|
+
instead. Example:
|
27
|
+
|
28
|
+
```shell
|
29
|
+
consul-templaterb -c http://localhost:8500 \
|
30
|
+
--template samples/consul-ui/consul-services-ui.html:samples/consul-ui/index.html \
|
31
|
+
samples/consul-ui/consul_template.json.erb
|
32
|
+
```
|
33
|
+
|
34
|
+
Will generate index.html and consul_template.json in your directory, so you might serve it directly.
|
35
|
+
|
36
|
+
### Filtering services
|
37
|
+
|
38
|
+
This app supports the following environement variables:
|
39
|
+
|
40
|
+
* SERVICES_TAG_FILTER: basic tag filter for service (default HTTP)
|
41
|
+
* INSTANCE_MUST_TAG: Second level of filtering (optional, default to SERVICES_TAG_FILTER)
|
42
|
+
* INSTANCE_EXCLUDE_TAG: Exclude instances having the given tag (default: canary)
|
43
|
+
* EXCLUDE_SERVICES: comma-separated services to exclude (default: consul-agent-http,mesos-slave,mesos-agent-watcher)
|
@@ -77,14 +77,15 @@
|
|
77
77
|
check['notes'] = ncheck['Notes']
|
78
78
|
checks.push(check)
|
79
79
|
end
|
80
|
+
meta = snode['Service']['Meta']
|
80
81
|
server = { frontend_id: "backend_http__#{service_name}",
|
81
|
-
id:
|
82
|
-
name:
|
83
|
-
sMeta:
|
84
|
-
addr:
|
85
|
-
port:
|
86
|
-
tags:
|
87
|
-
checks:
|
82
|
+
id: snode['Service']['ID'],
|
83
|
+
name: snode['Node']['Node'],
|
84
|
+
sMeta: meta ? meta : [],
|
85
|
+
addr: snode.service_address,
|
86
|
+
port: snode['Service']['Port'],
|
87
|
+
tags: snode['Service']['Tags'],
|
88
|
+
checks: checks,
|
88
89
|
}
|
89
90
|
service[:instances] << server
|
90
91
|
end
|
@@ -218,7 +218,7 @@ function serviceTitleGenerator(instance) {
|
|
218
218
|
|
219
219
|
var instanceLink = document.createElement('a');
|
220
220
|
if (protocol != null) {
|
221
|
-
instanceLink.setAttribute('href', protocol + instance.
|
221
|
+
instanceLink.setAttribute('href', protocol + instance.addr + ':' + instance.port);
|
222
222
|
instanceLink.setAttribute('target', '_blank');
|
223
223
|
}
|
224
224
|
instanceLink.appendChild(document.createTextNode(instance.name + ':' + instance.port));
|
@@ -54,7 +54,7 @@
|
|
54
54
|
<ul>
|
55
55
|
<% service(service_name).sort {|a,b| a['Node']['Node'] <=> b['Node']['Node'] }.each do |snode|
|
56
56
|
tags = snode['Service']['Tags'].sort
|
57
|
-
addr = snode
|
57
|
+
addr = snode.service_address
|
58
58
|
port_num = snode['Service']['Port'].to_i
|
59
59
|
port = port_num && port_num > 0 ? ":#{port_num}" : ''
|
60
60
|
url = if tags.include? 'https'
|
@@ -34,7 +34,7 @@
|
|
34
34
|
service(service_name).sort {|a,b| a['Node']['Node'] <=> b['Node']['Node'] }.each do |snode|
|
35
35
|
xnode = REXML::Element.new 'service-instance'
|
36
36
|
xnode.add_attribute 'id', snode['Node']['ID'] if snode['Node']['ID']
|
37
|
-
xnode.add_attribute 'address', snode
|
37
|
+
xnode.add_attribute 'address', snode.service_address
|
38
38
|
xnode.add_attribute 'name', snode['Node']['Name']
|
39
39
|
xnode.add_attribute 'port', snode['Service']['Port'].to_i
|
40
40
|
xnode.add_attribute 'tags', snode['Service']['Tags'].sort.join(',')
|
@@ -157,7 +157,7 @@ backend be_<%= service_name %>
|
|
157
157
|
mode http
|
158
158
|
balance leastconn
|
159
159
|
<% nodes.each_with_index do |node, idx|
|
160
|
-
%> server srv<%= idx %> <%= node
|
160
|
+
%> server srv<%= idx %> <%= node.service_address%>:<%= node['Service']['Port'] %><%= compute_attributes(node) %>
|
161
161
|
<% end
|
162
162
|
end
|
163
163
|
%>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<%
|
2
|
+
require 'base64'
|
3
|
+
require 'json'
|
4
|
+
require 'date'
|
5
|
+
@current_time = Time.now.utc
|
6
|
+
def display_holder(holder, value)
|
7
|
+
begin
|
8
|
+
holder_date = Time.parse(value)
|
9
|
+
status = 'success'
|
10
|
+
diff = (@current_time - holder_date).round(0)
|
11
|
+
status = 'warning' if diff > 3600
|
12
|
+
status = 'danger' if diff > 7200
|
13
|
+
diff_txt = "#{diff % 3600} seconds"
|
14
|
+
diff_txt = "#{(diff % 86400) / 3600} hours, #{diff_txt}" if diff > 3600
|
15
|
+
diff_txt = "#{diff / 86400} days, #{diff_txt}" if diff > 86400
|
16
|
+
rescue StandardError => e
|
17
|
+
status = 'info'
|
18
|
+
holder_date = "Cannot parse date: #{e}"
|
19
|
+
diff_txt = "Error Parsing date #{value}"
|
20
|
+
end
|
21
|
+
[holder, holder_date, "#{diff_txt} ago", status]
|
22
|
+
end
|
23
|
+
|
24
|
+
datacenters.each do |dc|
|
25
|
+
kv('choregraphie', dc:dc, recurse:true).each do |tuple|
|
26
|
+
ckey = tuple['Key'].gsub('/', '-')
|
27
|
+
if tuple['Value'].nil?
|
28
|
+
json = []
|
29
|
+
holders = []
|
30
|
+
else
|
31
|
+
json = JSON.parse(Base64.decode64(tuple['Value']))
|
32
|
+
holders = json['holders']
|
33
|
+
end
|
34
|
+
if holders.count > 0
|
35
|
+
holders.each_pair do |key,value|
|
36
|
+
if value.is_a?(Hash)
|
37
|
+
value.each_pair do |k, v|
|
38
|
+
host, holder_date, diff_txt, status = display_holder(k, v)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
host, holder_date, diff_txt, status = display_holder(key, value)
|
42
|
+
end
|
43
|
+
%><%= "#{host} ; #{dc} ; #{holder_date} ; #{status} ; #{ckey} ; #{diff_txt}" %>
|
44
|
+
<%
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
%>
|
data/samples/ha_proxy.cfg.erb
CHANGED
@@ -88,7 +88,7 @@ backend backend_http__<%= service_name %>
|
|
88
88
|
mode http
|
89
89
|
balance leastconn
|
90
90
|
<% nodes.each do |node|
|
91
|
-
%> server <%= node['Node']['Node']%>_<%= node['Service']['Port'] %> <%= node
|
91
|
+
%> server <%= node['Node']['Node']%>_<%= node['Service']['Port'] %> <%= node.service_address%>:<%= node['Service']['Port'] %><%= compute_attributes(node) %>
|
92
92
|
<% end
|
93
93
|
end
|
94
94
|
%>
|
data/samples/nodes.html.erb
CHANGED
@@ -28,7 +28,7 @@ end %>
|
|
28
28
|
if service_per_node.key?(snode['Node'])
|
29
29
|
service_per_node[snode['Node']].each do |service|
|
30
30
|
tags = service['Service']['Tags'].sort
|
31
|
-
addr = service
|
31
|
+
addr = service.service_address
|
32
32
|
port_num = service['Service']['Port'].to_i
|
33
33
|
port = port_num && port_num > 0 ? ":#{port_num}" : ''
|
34
34
|
url = if tags.include? 'https'
|
data/samples/services.html.erb
CHANGED
@@ -101,7 +101,7 @@ require 'date'
|
|
101
101
|
<div class="list-group">
|
102
102
|
<% nodes_sorted.each do |snode|
|
103
103
|
tags = snode['Service']['Tags'].sort
|
104
|
-
addr = snode
|
104
|
+
addr = snode.service_address
|
105
105
|
port_num = snode['Service']['Port'].to_i
|
106
106
|
port = port_num && port_num > 0 ? ":#{port_num}" : ''
|
107
107
|
url = if tags.include? 'https'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: consul-templaterb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SRE Core Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -171,6 +171,7 @@ files:
|
|
171
171
|
- samples/checks.html.erb
|
172
172
|
- samples/common/footer.html.erb
|
173
173
|
- samples/common/header.html.erb
|
174
|
+
- samples/consul-ui/README.md
|
174
175
|
- samples/consul-ui/common/header.html.erb
|
175
176
|
- samples/consul-ui/consul-services-ui.html.erb
|
176
177
|
- samples/consul-ui/consul_template.json.erb
|
@@ -182,6 +183,7 @@ files:
|
|
182
183
|
- samples/consul_template.xml.erb
|
183
184
|
- samples/criteo/haproxy.cfg.erb
|
184
185
|
- samples/criteo_choregraphies.html.erb
|
186
|
+
- samples/criteo_choregraphies.txt.erb
|
185
187
|
- samples/ha_proxy.cfg.erb
|
186
188
|
- samples/keys.html.erb
|
187
189
|
- samples/nodes.html.erb
|
@@ -211,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
213
|
version: '0'
|
212
214
|
requirements: []
|
213
215
|
rubyforge_project:
|
214
|
-
rubygems_version: 2.7.
|
216
|
+
rubygems_version: 2.7.7
|
215
217
|
signing_key:
|
216
218
|
specification_version: 4
|
217
219
|
summary: Implementation of Consul template using Ruby and .erb templating language
|