consul-templaterb 1.18.5 → 1.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -8
- data/CHANGELOG.md +15 -0
- data/README.md +10 -12
- data/TemplateAPI.md +4 -0
- data/lib/consul/async/consul_template.rb +10 -0
- data/lib/consul/async/version.rb +1 -1
- data/samples/consul-ui/common/header.html.erb +0 -6
- data/samples/consul-ui/consul-keys-ui.html.erb +2 -1
- data/samples/consul-ui/consul-nodes-ui.html.erb +15 -8
- data/samples/consul-ui/consul-services-ui.html.erb +21 -8
- data/samples/consul-ui/css/style.css +7 -3
- data/samples/consul-ui/js/keys.js +71 -115
- data/samples/consul-ui/js/nodes.js +224 -238
- data/samples/consul-ui/js/service.js +319 -343
- data/samples/consul-ui/js/timeline.js +12 -7
- data/samples/consul-ui/js/types.js +317 -0
- data/samples/consul-ui/js/utils.js +362 -334
- data/samples/tools/find_all_maintenance_nodes.txt.erb +25 -0
- metadata +4 -9
- data/samples/checks.html.erb +0 -130
- data/samples/common/footer.html.erb +0 -8
- data/samples/common/header.html.erb +0 -45
- data/samples/criteo_choregraphies.txt.erb +0 -49
- data/samples/keys.html.erb +0 -42
- data/samples/nodes.html.erb +0 -52
- data/samples/services.html.erb +0 -134
@@ -0,0 +1,25 @@
|
|
1
|
+
node ; Status
|
2
|
+
<%
|
3
|
+
# find all the failing services.
|
4
|
+
# Usage: consul-templaterb --once samples/tools/find_all_failing_services.txt.erb
|
5
|
+
#
|
6
|
+
# Environment variables:
|
7
|
+
# * `CONSUL_SERVICE_FILTER` : regexp to filter services `.*` by default
|
8
|
+
# * `CONSUL_DC_FILTER`: regexp to filter datacenters `.*` by default
|
9
|
+
|
10
|
+
node_filter = Regexp.new(ENV['CONSUL_NODE_FILTER'] || '.*')
|
11
|
+
dc_filter = Regexp.new(ENV['CONSUL_DC_FILTER'] || '.*')
|
12
|
+
datacenters.each do |dc|
|
13
|
+
next unless dc_filter.match(dc)
|
14
|
+
nodes(dc: dc).each do |node|
|
15
|
+
#warn node.inspect
|
16
|
+
next unless node_filter.match(node['Node'])
|
17
|
+
checks_for_node(node['Node'], dc: dc).each do |check|
|
18
|
+
if check['Status'] != 'passing' && check['CheckID'] == '_node_maintenance'
|
19
|
+
%>"<%= check['Node'] %>" ; "<%= check['Notes'] %>"
|
20
|
+
<%
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
%>
|
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.19.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: 2019-
|
11
|
+
date: 2019-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|
@@ -192,9 +192,6 @@ files:
|
|
192
192
|
- lib/consul/async/vault_endpoint.rb
|
193
193
|
- lib/consul/async/version.rb
|
194
194
|
- samples/all_services.txt.erb
|
195
|
-
- samples/checks.html.erb
|
196
|
-
- samples/common/footer.html.erb
|
197
|
-
- samples/common/header.html.erb
|
198
195
|
- samples/consul-ui/README.md
|
199
196
|
- samples/consul-ui/common/header.html.erb
|
200
197
|
- samples/consul-ui/consul-keys-ui.html.erb
|
@@ -210,6 +207,7 @@ files:
|
|
210
207
|
- samples/consul-ui/js/nodes.js
|
211
208
|
- samples/consul-ui/js/service.js
|
212
209
|
- samples/consul-ui/js/timeline.js
|
210
|
+
- samples/consul-ui/js/types.js
|
213
211
|
- samples/consul-ui/js/utils.js
|
214
212
|
- samples/consul-ui/ringbuffer.rb
|
215
213
|
- samples/consul-ui/timeline.json.erb
|
@@ -221,23 +219,20 @@ files:
|
|
221
219
|
- samples/consul_template.xml.erb
|
222
220
|
- samples/consul_template_broken.txt.erb
|
223
221
|
- samples/criteo/haproxy.cfg.erb
|
224
|
-
- samples/criteo_choregraphies.txt.erb
|
225
222
|
- samples/debug/compare_connect_services.txt.erb
|
226
223
|
- samples/ha_proxy.cfg.erb
|
227
224
|
- samples/haproxy_dns.cfg.erb
|
228
225
|
- samples/hosts.erb
|
229
226
|
- samples/hosts_per_services.erb
|
230
|
-
- samples/keys.html.erb
|
231
227
|
- samples/kv_yaml_to_json.json.erb
|
232
228
|
- samples/list_ruby_versions_from_rubygems.txt.erb
|
233
229
|
- samples/metrics.erb
|
234
|
-
- samples/nodes.html.erb
|
235
230
|
- samples/prometheus_consul_coordinates.erb
|
236
231
|
- samples/render_template_from_kv.erb
|
237
232
|
- samples/sample_keys.html.erb
|
238
233
|
- samples/service_checks_metrics.erb
|
239
|
-
- samples/services.html.erb
|
240
234
|
- samples/tools/find_all_failing_services.txt.erb
|
235
|
+
- samples/tools/find_all_maintenance_nodes.txt.erb
|
241
236
|
- samples/tools/find_all_nodes_without_id.txt.erb
|
242
237
|
- samples/vault-ldap.txt.erb
|
243
238
|
homepage: https://rubygems.org/gems/consul-templaterb
|
data/samples/checks.html.erb
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
<%= render_file('common/header.html.erb', title: 'Consul Checks') %>
|
2
|
-
<%
|
3
|
-
# This template can be configure the following way with environment variables
|
4
|
-
# Environment variables to filter services/instances
|
5
|
-
# SERVICES_TAG_FILTER: basic tag filter for service (default HTTP)
|
6
|
-
services_tag_filter = ENV['SERVICES_TAG_FILTER']
|
7
|
-
def status_to_class(status)
|
8
|
-
if status == 'passing'
|
9
|
-
'success'
|
10
|
-
elsif status == 'warning'
|
11
|
-
'warning'
|
12
|
-
elsif status == 'critical'
|
13
|
-
'danger'
|
14
|
-
else
|
15
|
-
'info'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
%>
|
19
|
-
<style>
|
20
|
-
.check {
|
21
|
-
transition: opacity 1s ease-out;
|
22
|
-
}
|
23
|
-
</style>
|
24
|
-
<script>//<!--
|
25
|
-
function updateStates() {
|
26
|
-
states = ['passing', 'warning', 'critical']
|
27
|
-
stylesheet = document.getElementById('css-states');
|
28
|
-
txt = "";
|
29
|
-
for (var i in states) {
|
30
|
-
var s = states[i];
|
31
|
-
is_checked = document.getElementById('show_'+s).checked
|
32
|
-
var to_append = "." + s + " { ";
|
33
|
-
if (is_checked) {
|
34
|
-
to_append += "display: block"
|
35
|
-
} else {
|
36
|
-
to_append += "display:none"
|
37
|
-
}
|
38
|
-
to_append += " }\r\n"
|
39
|
-
txt += to_append;
|
40
|
-
}
|
41
|
-
stylesheet.textContent = txt;
|
42
|
-
}
|
43
|
-
//->
|
44
|
-
</script>
|
45
|
-
<div class="container-fluid">
|
46
|
-
<div class="row">
|
47
|
-
<nav class="col-2">
|
48
|
-
<ul>
|
49
|
-
<%
|
50
|
-
all_services = services(tag: services_tag_filter)
|
51
|
-
all_services.each do |service_name, tags|
|
52
|
-
%>
|
53
|
-
<li><a title="<%= tags.sort.join(', ') %>" href="#service_<%= service_name %>"><%= service_name %></a></li>
|
54
|
-
<% end %>
|
55
|
-
</ul>
|
56
|
-
</nav>
|
57
|
-
<main class="col-10">
|
58
|
-
<div class="float-right">
|
59
|
-
<span class="state-selector">
|
60
|
-
<input id="show_passing" type="checkbox" class="checks-visibility" value="passing" checked="checked" onchange="updateStates()"/>
|
61
|
-
<label for="show_passing"><span class="badge badge-success">Passing</span></label>
|
62
|
-
</span>
|
63
|
-
<span class="state-selector">
|
64
|
-
<input id="show_warning" type="checkbox" class="checks-visibility" value="warning" checked="checked" onchange="updateStates()"/>
|
65
|
-
<label for="show_warning"><span class="badge badge-warning">Warning</span></label>
|
66
|
-
</span>
|
67
|
-
<span class="state-selector">
|
68
|
-
<input id="show_critical" type="checkbox" class="checks-visibility" value="critical" checked="checked" onchange="updateStates()"/>
|
69
|
-
<label for="show_critical"><span class="badge badge-danger">Critical</span></label>
|
70
|
-
</span>
|
71
|
-
</div>
|
72
|
-
|
73
|
-
<h1 id="services">Services <%= services_tag_filter ? " tag: #{services_tag_filter}" : 'No filtering' %></h1>
|
74
|
-
<% all_services.each do |service_name, tags|
|
75
|
-
passing = 0
|
76
|
-
warning = 0
|
77
|
-
critical = 0
|
78
|
-
service_state = 'passing'
|
79
|
-
sum = 0
|
80
|
-
checks_for_service(service_name).each do |check|
|
81
|
-
st = check['Status']
|
82
|
-
sum += 1
|
83
|
-
case st
|
84
|
-
when 'warning'
|
85
|
-
warning += 1
|
86
|
-
when 'passing'
|
87
|
-
passing += 1
|
88
|
-
else
|
89
|
-
critical += 1
|
90
|
-
end
|
91
|
-
end
|
92
|
-
service_state = 'warning' if warning > 0
|
93
|
-
service_state = 'critical' if critical > 0
|
94
|
-
%>
|
95
|
-
<div class="service <%= service_state %>" id="service_<%= service_name %>">
|
96
|
-
<h2 class="service-name text-<%= status_to_class(service_state) %>">Service <%= service_name %>
|
97
|
-
<span class="float-right">
|
98
|
-
<span class="badge badge-pill badge-success"><%= passing > 0 ? passing : nil %></span>
|
99
|
-
<span class="badge badge-pill badge-warning"><%= warning > 0 ? warning : nil %></span>
|
100
|
-
<span class="badge badge-pill badge-danger"><%= critical > 0 ? critical : nil %></span>
|
101
|
-
</span>
|
102
|
-
</h2>
|
103
|
-
<% if sum > 0
|
104
|
-
%><div class="progress">
|
105
|
-
<div title="<%= "#{passing} / #{sum}" %>" class="progress-bar bg-success" role="progressbar" style="width:<%= (100.0 * passing / sum).round(2) %>%" aria-valuenow="<%= passing %>" aria-valuemin="0" aria-valuemax="<%= sum %>"></div>
|
106
|
-
<div title="<%= "#{warning} / #{sum}" %>" class="progress-bar bg-warning" role="progressbar" style="width:<%= (100.0 * warning / sum).round(2) %>%" aria-valuenow="<%= warning %>" aria-valuemin="0" aria-valuemax="<%= sum %>"></div>
|
107
|
-
<div title="<%= "#{critical} / #{sum}" %>" class="progress-bar bg-danger" role="progressbar" style="width:<%= (100.0 * critical / sum).round(2) %>%" aria-valuenow="<%= critical %>" aria-valuemin="0" aria-valuemax="<%= sum %>"></div>
|
108
|
-
</div>
|
109
|
-
<% end %>
|
110
|
-
<div class="list-group">
|
111
|
-
<% checks_for_service(service_name).each do |check| %>
|
112
|
-
<div class="list-group-item check <%= check['Status'] %>" id="<%= check['Node'] + check['CheckID'] %>">
|
113
|
-
<div class="d-flex align-items-center justify-content-between">
|
114
|
-
<h5>
|
115
|
-
<%= check['Name'] %> / <%= check['Node'] %>
|
116
|
-
</h5>
|
117
|
-
<span class="badge badge-pill badge-<%= status_to_class(check['Status']) %>"><%= check['Status'] %></span>
|
118
|
-
</div>
|
119
|
-
<p><%= ERB::Util.html_escape(check['Notes']) %></p>
|
120
|
-
<code><%= ERB::Util.html_escape(check['Output']) %></code>
|
121
|
-
</div>
|
122
|
-
<% end %>
|
123
|
-
</div>
|
124
|
-
</div>
|
125
|
-
<% end %>
|
126
|
-
</main>
|
127
|
-
</div>
|
128
|
-
</div>
|
129
|
-
<script>updateStates();</script>
|
130
|
-
<%= render_file('common/footer.html.erb') %>
|
@@ -1,8 +0,0 @@
|
|
1
|
-
<!-- Bootstrap core JavaScript
|
2
|
-
================================================== -->
|
3
|
-
<!-- Latest compiled and minified JavaScript -->
|
4
|
-
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
5
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
6
|
-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
7
|
-
</body>
|
8
|
-
</html>
|
@@ -1,45 +0,0 @@
|
|
1
|
-
<%
|
2
|
-
# This template can be configure the following way with environment variables
|
3
|
-
# CONSUL_TOOLS_SUFFIX: suffix for the address of consul tools
|
4
|
-
# CONSUL_TOOLS_PREFIX: prefix for the address of consul tools
|
5
|
-
# CONSUL_TOOLS: comma sperated list of consul tools
|
6
|
-
tools = (ENV['CONSUL_TOOLS'] || 'criteo_choregraphies,checks,services,nodes,keys').split(",")
|
7
|
-
suffix = ENV['CONSUL_TOOLS_PREFIX'] || '.html'
|
8
|
-
prefix = ENV['CONSUL_TOOLS_SUFFIX'] || ''
|
9
|
-
%><!DOCTYPE html>
|
10
|
-
<html lang="en">
|
11
|
-
<head>
|
12
|
-
<meta charset="utf-8"/>
|
13
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
|
14
|
-
<meta name="description" content="Display Consul information"/>
|
15
|
-
<meta name="author" content="Criteo"/>
|
16
|
-
<meta http-equiv="refresh" content="<%= param('refresh', ENV['REFRESH'] || '600') %>"/>
|
17
|
-
<title><%= param('title', 'Consul Real Time information') %></title>
|
18
|
-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
19
|
-
<style>
|
20
|
-
body {
|
21
|
-
padding-top: 5rem;
|
22
|
-
}
|
23
|
-
.check {
|
24
|
-
transition: opacity 1s ease-out;
|
25
|
-
}
|
26
|
-
</style>
|
27
|
-
<style id="css-states">
|
28
|
-
</style>
|
29
|
-
</head>
|
30
|
-
<body>
|
31
|
-
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
32
|
-
<a class="navbar-brand" href="#">Consul</a>
|
33
|
-
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
34
|
-
<span class="navbar-toggler-icon"></span>
|
35
|
-
</button>
|
36
|
-
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
37
|
-
<ul class="navbar-nav mr-auto">
|
38
|
-
<% tools.each do |tool| %>
|
39
|
-
<li class="nav-item">
|
40
|
-
<a class="nav-link" href="<%= prefix + tool + suffix %>"><%= tool.gsub('_', ' ') %></a>
|
41
|
-
</li>
|
42
|
-
<% end %>
|
43
|
-
</ul>
|
44
|
-
</div>
|
45
|
-
</nav>
|
@@ -1,49 +0,0 @@
|
|
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/keys.html.erb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
<%= render_file('common/header.html.erb', title: 'Keys') %>
|
2
|
-
<% path = ENV['kv_path'] || '' %>
|
3
|
-
<% require 'base64'
|
4
|
-
require 'json'
|
5
|
-
require 'date'
|
6
|
-
%>
|
7
|
-
<main class="container">
|
8
|
-
<div>
|
9
|
-
<h1>Show all keys <%= path == '' ? '' : "under hierarchy #{path}" %></h1>
|
10
|
-
<div id="accordion">
|
11
|
-
<!-- LastModified: <%= kv(path, recurse:true).endpoint.stats.last_modified %> -->
|
12
|
-
<%
|
13
|
-
kv(path, recurse:true).each do |tuple|
|
14
|
-
key = tuple['Key']
|
15
|
-
val = "NO_VALUE"
|
16
|
-
if !tuple['Value'].nil?
|
17
|
-
begin
|
18
|
-
val = Base64.decode64(tuple['Value'])
|
19
|
-
rescue StdError => e
|
20
|
-
val = "#{e.inspect} for tuple['Value']"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
%>
|
24
|
-
<div class="card">
|
25
|
-
<div class="card-header" id="heading-<%= key %>">
|
26
|
-
<h5 class="mb-0">
|
27
|
-
<a href="#<%= key %>" class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse-<%= key %>" aria-expanded="true" aria-controls="collapse-<%= key %>">
|
28
|
-
<%= key %>
|
29
|
-
</a>
|
30
|
-
</h5>
|
31
|
-
<div id="collapse-<%= key %>" class="collapse" aria-labelledby="heading-<%= key %>" data-parent="#accordion">
|
32
|
-
<div class="card-body">
|
33
|
-
<pre class="pre-scrollable"><%= ERB::Util.html_escape(val) %></pre>
|
34
|
-
</div>
|
35
|
-
</div>
|
36
|
-
</div>
|
37
|
-
</div>
|
38
|
-
<% end %>
|
39
|
-
</div>
|
40
|
-
</div>
|
41
|
-
</main>
|
42
|
-
<%= render_file 'common/footer.html.erb' %>
|
data/samples/nodes.html.erb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
<%= render_file('common/header.html.erb', title: 'Nodes') %><%
|
2
|
-
service_tag_filter = ENV['SERVICES_TAG_FILTER'] || nil
|
3
|
-
# Services to hide
|
4
|
-
services_blacklist_raw = (ENV['EXCLUDE_SERVICES'] || 'lbl7.*,netsvc-probe.*,consul-probed.*').split(',')
|
5
|
-
services_blacklist = services_blacklist_raw.map { |v| Regexp.new(v) }
|
6
|
-
|
7
|
-
service_per_node = {}
|
8
|
-
services.each do |service_name, tags|
|
9
|
-
if !services_blacklist.any? {|r| r.match(service_name)}
|
10
|
-
service(service_name, tag: service_tag_filter).sort {|a,b| a['Node']['Node'] <=> b['Node']['Node'] }.each do |snode|
|
11
|
-
node_services = service_per_node[snode['Node']['Node']] || []
|
12
|
-
node_services.push(snode)
|
13
|
-
service_per_node[snode['Node']['Node']] = node_services
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end %>
|
17
|
-
|
18
|
-
<h1 id="nodes">List all nodes for DC, sorted by name</h1>
|
19
|
-
<ul class="list-group">
|
20
|
-
<% nodes.sort {|a,b| a['Node'] <=> b['Node'] }.each do |snode|
|
21
|
-
%><li id="node_<%= snode['ID'] %>" class="list-group-item">
|
22
|
-
<a href="ssh://<%= snode['Address']%>"><%= snode['Address'] %></a> <%= snode['Node'] %><%
|
23
|
-
snode['Meta'].each do |k,v|
|
24
|
-
if v && !v.empty?
|
25
|
-
%><span class="badge badge-pill badge-primary float-right"><%= k %>: <%= v%></span><%
|
26
|
-
end
|
27
|
-
end if snode['Meta']
|
28
|
-
%><div><%
|
29
|
-
if service_per_node.key?(snode['Node'])
|
30
|
-
service_per_node[snode['Node']].each do |service|
|
31
|
-
tags = service['Service']['Tags'].sort
|
32
|
-
addr = service.service_address
|
33
|
-
port_num = service['Service']['Port'].to_i
|
34
|
-
port = port_num && port_num > 0 ? ":#{port_num}" : ''
|
35
|
-
url = if tags.include? 'https'
|
36
|
-
"https://#{addr}#{port}"
|
37
|
-
elsif tags.include? 'http'
|
38
|
-
"http://#{addr}#{port}"
|
39
|
-
elsif tags.include? 'ftp'
|
40
|
-
"ftp://#{addr}#{port}"
|
41
|
-
else
|
42
|
-
nil
|
43
|
-
end
|
44
|
-
%> <a class="badge badge-secondary" href='<%= url %>'>
|
45
|
-
<%= service['Service']['Service'] %>: <%= port_num %>
|
46
|
-
</a>
|
47
|
-
<% end
|
48
|
-
end
|
49
|
-
%></div></li>
|
50
|
-
<% end %>
|
51
|
-
</ul>
|
52
|
-
<%= render_file 'common/footer.html.erb' %>
|
data/samples/services.html.erb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
<%
|
2
|
-
# This template can be configure the following way with environment variables
|
3
|
-
# Environment variables to filter services/instances
|
4
|
-
# SERVICES_TAG_FILTER: basic tag filter for service (default HTTP)
|
5
|
-
require 'base64'
|
6
|
-
require 'json'
|
7
|
-
require 'date'
|
8
|
-
|
9
|
-
services_tag_filter = ENV['SERVICES_TAG_FILTER']
|
10
|
-
def status_to_class(status)
|
11
|
-
if status == 'passing'
|
12
|
-
'success'
|
13
|
-
elsif status == 'warning'
|
14
|
-
'warning'
|
15
|
-
elsif status == 'critical'
|
16
|
-
'danger'
|
17
|
-
else
|
18
|
-
'info'
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def compute_node_status(snode)
|
23
|
-
state = 'passing'
|
24
|
-
return state unless snode['Checks']
|
25
|
-
snode['Checks'].each do |c|
|
26
|
-
case c['Status']
|
27
|
-
when 'critical'
|
28
|
-
return 'critical'
|
29
|
-
when 'warning'
|
30
|
-
state = 'warning'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
state
|
34
|
-
end
|
35
|
-
|
36
|
-
def compute_service_status(snodes)
|
37
|
-
passing = 0
|
38
|
-
warning = 0
|
39
|
-
critical = 0
|
40
|
-
sum = 0
|
41
|
-
snodes.each do |snode|
|
42
|
-
st = compute_node_status(snode)
|
43
|
-
sum += 1
|
44
|
-
case st
|
45
|
-
when 'passing'
|
46
|
-
passing += 1
|
47
|
-
when 'warning'
|
48
|
-
warning += 1
|
49
|
-
else
|
50
|
-
critical += 1
|
51
|
-
end
|
52
|
-
end
|
53
|
-
[passing, warning, critical, sum]
|
54
|
-
end
|
55
|
-
%><%= render_file('common/header.html.erb', title: 'Services') %>
|
56
|
-
<nav>
|
57
|
-
<ul>
|
58
|
-
<li><a href="#datacenters">DataCenters</a></li>
|
59
|
-
<li><a href="#list_services">List of services</a></li>
|
60
|
-
<li><a href="#services">Services with instances</a></li>
|
61
|
-
</ul>
|
62
|
-
</nav>
|
63
|
-
|
64
|
-
<div class="container-fluid">
|
65
|
-
<div class="row">
|
66
|
-
<nav id="list_services" class="col-2">
|
67
|
-
<ul>
|
68
|
-
<%
|
69
|
-
all_services = services(tag: services_tag_filter)
|
70
|
-
all_services.each do |service_name, tags|
|
71
|
-
%>
|
72
|
-
<li><a title="<%= tags.sort.join(', ') %>" href="#service_<%= service_name %>"><%= service_name %></a></li>
|
73
|
-
<% end %>
|
74
|
-
</ul>
|
75
|
-
</nav>
|
76
|
-
<main class="col-10">
|
77
|
-
<h1 id="datacenters">List of all datacenters</h1>
|
78
|
-
<ul>
|
79
|
-
<% datacenters.each do |dc| %>
|
80
|
-
<li id="dc_<%=dc %>%"><%= dc %> with <%= services(dc:dc).keys.count %> services, <%= nodes(dc:dc).count %> nodes</li>
|
81
|
-
<% end %>
|
82
|
-
</ul>
|
83
|
-
<h1 id="services">List all services instances sorted by node name</h1>
|
84
|
-
<% services.each do |service_name, tags|
|
85
|
-
service_group = service(service_name)
|
86
|
-
nodes_sorted = service_group.sort {|a,b| a['Node']['Node'] <=> b['Node']['Node'] }
|
87
|
-
passing, warning, critical, sum = compute_service_status(nodes_sorted)
|
88
|
-
service_state = 'passing'
|
89
|
-
service_state = 'warning' if warning > 0
|
90
|
-
service_state = 'critical' if critical > 0
|
91
|
-
%>
|
92
|
-
<div class="service <%= service_state %>" id="service_<%= service_name %>">
|
93
|
-
<h2 class="text-<%= status_to_class(service_state) %>" title="<%= tags.join(', ') %>"><%= service_name %><a class="qlink" href="#service_<%= service_name %>">🔗</a></h2>
|
94
|
-
<% if sum > 0
|
95
|
-
%><div class="progress">
|
96
|
-
<div title="<%= "#{passing} / #{sum}" %>" class="progress-bar bg-success" role="progressbar" style="width:<%= (100.0 * passing / sum).round(2) %>%" aria-valuenow="<%= passing %>" aria-valuemin="0" aria-valuemax="<%= sum %>"></div>
|
97
|
-
<div title="<%= "#{warning} / #{sum}" %>" class="progress-bar bg-warning" role="progressbar" style="width:<%= (100.0 * warning / sum).round(2) %>%" aria-valuenow="<%= warning %>" aria-valuemin="0" aria-valuemax="<%= sum %>"></div>
|
98
|
-
<div title="<%= "#{critical} / #{sum}" %>" class="progress-bar bg-danger" role="progressbar" style="width:<%= (100.0 * critical / sum).round(2) %>%" aria-valuenow="<%= critical %>" aria-valuemin="0" aria-valuemax="<%= sum %>"></div>
|
99
|
-
</div>
|
100
|
-
<% end %>
|
101
|
-
<div class="list-group">
|
102
|
-
<% nodes_sorted.each do |snode|
|
103
|
-
tags = snode['Service']['Tags'].sort
|
104
|
-
addr = snode.service_address
|
105
|
-
port_num = snode['Service']['Port'].to_i
|
106
|
-
port = port_num && port_num > 0 ? ":#{port_num}" : ''
|
107
|
-
url = if tags.include? 'https'
|
108
|
-
"https://#{addr}#{port}"
|
109
|
-
elsif tags.include? 'http'
|
110
|
-
"http://#{addr}#{port}"
|
111
|
-
elsif tags.include? 'ftp'
|
112
|
-
"ftp://#{addr}#{port}"
|
113
|
-
else
|
114
|
-
nil
|
115
|
-
end
|
116
|
-
%><div class="list-group-item check"><a <%= url ? "href=\"#{url}\"" : nil %>><%=
|
117
|
-
snode['Node']['Node'] %><%= port %></a>
|
118
|
-
<span class="tags"><%
|
119
|
-
snode['Service']['Tags'].sort.each do |t|
|
120
|
-
%><span class="badge badge-pill"><%= t %></span><%
|
121
|
-
end
|
122
|
-
%></span>
|
123
|
-
<span class="float-right statuses"><%
|
124
|
-
snode['Checks'].each do |c| %> <span title="<%= c['Name']%>" class="badge badge-pill badge-<%= status_to_class(c['Status']) %>"><%= c['Status']
|
125
|
-
%></span><% end if snode['Checks'] %></span></div>
|
126
|
-
<% end %>
|
127
|
-
</div>
|
128
|
-
</div>
|
129
|
-
<% end
|
130
|
-
%>
|
131
|
-
</main>
|
132
|
-
</div>
|
133
|
-
</div>
|
134
|
-
<%= render_file 'common/footer.html.erb' %>
|