consul-templaterb 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +17 -0
- data/lib/consul/async/version.rb +1 -1
- data/samples/consul-ui/consul-services-ui.html.erb +1 -1
- data/samples/consul-ui/consul_template.json.erb +7 -3
- data/samples/consul-ui/css/style.css +11 -0
- data/samples/consul-ui/js/service.js +61 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: feb7928f78cdbbfae6a96b7b6150c569addb523d94db80024c4493989cf1df4c
|
4
|
+
data.tar.gz: 93be5f37da47ebfefdfe40e836e28d0f5f440a5481da2db38c708c245d64769a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d475a88889816f29899ec899c13614af8841bc984fb86ff864f6a6a8f9d50f31507244b2954a7e2c374b40d75412c39a90b218b9d11355e9af51d0258ea7975d
|
7
|
+
data.tar.gz: 0f52de542d465e7a962a81025c226111df1725f4bafdc53f591827607a08bc5345e8160e2b791517135b2fbaad27b23309c71acb91ac406cb480fa8c3ab9d8df
|
data/CHANGELOG.md
CHANGED
@@ -4,9 +4,18 @@
|
|
4
4
|
|
5
5
|
IMPROVEMENTS:
|
6
6
|
|
7
|
+
## 1.1.2 (May 17, 2018)
|
8
|
+
|
9
|
+
IMPROVEMENTS:
|
10
|
+
|
11
|
+
* samples/consul-ui now display number of instances passing/warning/critical
|
12
|
+
* samples/consul-ui allow to filter per status, tags or instance name
|
13
|
+
* samples/consul-ui now display tags in list
|
14
|
+
|
7
15
|
## 1.1.1 (May 15, 2018)
|
8
16
|
|
9
17
|
IMPROVEMENTS:
|
18
|
+
|
10
19
|
* Use 60 seconds of cleanup to avoid over-cleaning up endpoints
|
11
20
|
* Use same environment variables to filter services in nodes.html.erb
|
12
21
|
|
data/README.md
CHANGED
@@ -243,7 +243,24 @@ templates. Also have a look to [samples/](samples/) directory to have full worki
|
|
243
243
|
|
244
244
|
## Development
|
245
245
|
|
246
|
+
### Quick start
|
247
|
+
|
246
248
|
We recommend using bundle using `bundle install`, you can now run `bundle exec bin/consul-templaterb`.
|
249
|
+
Help is available running `bundle exec bin/consul-templaterb --help`
|
250
|
+
|
251
|
+
The following example will generate static HTML pages and JSON data for `consul-ui`:
|
252
|
+
```
|
253
|
+
bundle exec bin/consul-templaterb -c your.consul.agent:8500 samples/consul-ui/*.erb
|
254
|
+
```
|
255
|
+
|
256
|
+
If you need remote calls, you need an HTTP server. A simple way to have one is using Python's simple HTTP
|
257
|
+
server. Example for `consul-ui`:
|
258
|
+
```
|
259
|
+
cd samples/consul-ui
|
260
|
+
python -m SimpleHTTPServer
|
261
|
+
```
|
262
|
+
|
263
|
+
### Installation
|
247
264
|
|
248
265
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
249
266
|
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
|
data/lib/consul/async/version.rb
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
<div class="row mx-0">
|
8
8
|
<div id="filter-menu" class="col-4 col-m-3 px-4 pt-4">
|
9
9
|
<div class="form-group">
|
10
|
-
<input id="service-filter" type="text" placeholder="filter" class="form-control" >
|
10
|
+
<input id="service-filter" type="text" placeholder="filter by name or tags" class="form-control" >
|
11
11
|
</div>
|
12
12
|
<div id="service-wrapper" >
|
13
13
|
<ul id="service-list" class="list-group">
|
@@ -41,11 +41,13 @@
|
|
41
41
|
attributes = "#{attributes} weight #{w}" if w.positive?
|
42
42
|
end
|
43
43
|
backends = {}
|
44
|
+
tags_per_service = {}
|
44
45
|
services(tag: service_tag_filter).each do |service_name, tags|
|
45
46
|
if !services_blacklist.include?(service_name) && (instance_must_tag.nil? || tags.include?(instance_must_tag))
|
47
|
+
tags_per_service[service_name] = tags.sort
|
46
48
|
the_backends = []
|
47
49
|
service(service_name).sort {|a,b| a['Node']['Node'] <=> b['Node']['Node'] }.each do |snode|
|
48
|
-
tags_of_instance = snode['Service']['Tags']
|
50
|
+
tags_of_instance = snode['Service']['Tags'].sort
|
49
51
|
if (instance_must_tag.nil? || tags_of_instance.include?(instance_must_tag)) && !tags_of_instance.include?(instance_exclude_tag)
|
50
52
|
the_backends << snode if snode['Service']['Port']
|
51
53
|
end
|
@@ -60,14 +62,15 @@
|
|
60
62
|
service = {
|
61
63
|
name: service_name,
|
62
64
|
count: nodes.count,
|
63
|
-
|
65
|
+
tags: tags_per_service[service_name],
|
66
|
+
instances: [],
|
64
67
|
}
|
65
68
|
json_backends[service_name] = service
|
66
69
|
nodes.each do |snode|
|
67
70
|
checks = []
|
68
71
|
snode['Checks'].each do |ncheck|
|
69
72
|
check = {}
|
70
|
-
check['checkid'] = ncheck['CheckID']
|
73
|
+
check['checkid'] = ncheck['ID'] || ncheck['CheckID']
|
71
74
|
check['name'] = ncheck['Name']
|
72
75
|
check['output'] = ncheck['Output']
|
73
76
|
check['status'] = ncheck['Status']
|
@@ -77,6 +80,7 @@
|
|
77
80
|
server = { frontend_id: "backend_http__#{service_name}",
|
78
81
|
id: snode['Service']['ID'],
|
79
82
|
name: snode['Node']['Node'],
|
83
|
+
sMeta: snode['Service']['Meta'],
|
80
84
|
addr: snode['Node']['Address'],
|
81
85
|
port: snode['Service']['Port'],
|
82
86
|
tags: snode['Service']['Tags'],
|
@@ -12,6 +12,17 @@
|
|
12
12
|
border-color: rgba(0,0,0,.125);
|
13
13
|
}
|
14
14
|
|
15
|
+
.service-tags {
|
16
|
+
overflow: scroll;
|
17
|
+
max-height: 2.2em !important;
|
18
|
+
}
|
19
|
+
|
20
|
+
.service-tags .badge {
|
21
|
+
max-width: 8em;
|
22
|
+
text-overflow: ellipsis;
|
23
|
+
overflow: hidden;
|
24
|
+
}
|
25
|
+
|
15
26
|
#service-wrapper .list-group-item:last-child, #instances-wrapper .list-group-item:last-child {
|
16
27
|
border-bottom-width: 0px;
|
17
28
|
border-bottom-left-radius: 0px;
|
@@ -24,8 +24,10 @@ class ConsulService {
|
|
24
24
|
if (urlParam) {
|
25
25
|
var nodes = document.getElementById('service-list').childNodes;
|
26
26
|
for(var i in nodes) {
|
27
|
-
if($(nodes[i]).html() == urlParam) {
|
28
|
-
|
27
|
+
if($(nodes[i]).find(".service-name").html() == urlParam) {
|
28
|
+
var selectedElement = $(nodes[i])
|
29
|
+
this.selectService(selectedElement);
|
30
|
+
selectedElement.focus()
|
29
31
|
break;
|
30
32
|
}
|
31
33
|
}
|
@@ -39,9 +41,32 @@ class ConsulService {
|
|
39
41
|
}
|
40
42
|
|
41
43
|
reloadServiceList() {
|
42
|
-
for (var
|
43
|
-
var
|
44
|
-
|
44
|
+
for (var serviceName in this.data.services) {
|
45
|
+
var service = this.data.services[serviceName];
|
46
|
+
var serviceStatus = buildServiceStatus(service);
|
47
|
+
var listItem = '<button type="button" onfocus="consulService.onClickServiceName(this)" onclick="consulService.onClickServiceName(this)" value="' + serviceName + '" class="list-group-item list-group-item-action">';
|
48
|
+
listItem += '<div class="statuses" style="float:right">'
|
49
|
+
var globalStatus = 'dark'
|
50
|
+
if (!!serviceStatus['passing']) {
|
51
|
+
listItem += '<span class="badge badge-pill badge-success" style="margin-right:10px;">' + serviceStatus['passing'] + '</span>';
|
52
|
+
}
|
53
|
+
if (!!serviceStatus['warning']) {
|
54
|
+
listItem += '<span class="badge badge-pill badge-warning" style="margin-right:10px;">' + serviceStatus['warning'] + '</span>';
|
55
|
+
if (globalStatus == 'dark') {
|
56
|
+
globalStatus = 'warning'
|
57
|
+
}
|
58
|
+
}
|
59
|
+
if (!!serviceStatus['critical']) {
|
60
|
+
listItem += '<span class="badge badge-pill badge-danger" style="margin-right:10px;">' + serviceStatus['critical'] + '</span>';
|
61
|
+
globalStatus = 'critical'
|
62
|
+
}
|
63
|
+
listItem+= ' / <span class="badge badge-pill badge-dark">' + (serviceStatus['total'] || 0) + '</span></div>';
|
64
|
+
listItem += '<div class="service-name text-' + globalStatus + '">' + serviceName + '</div>';
|
65
|
+
listItem += '<div class="service-tags">'
|
66
|
+
for (var i = 0; i < service.tags.length; i++) {
|
67
|
+
listItem += '<span title="' + service.tags[i] + '" class="badge badge-pill badge-' + (i%2?'secondary':'info') + '" style="float:right;">' + (service.tags[i]) + '</span> ';
|
68
|
+
}
|
69
|
+
listItem += '</div>'
|
45
70
|
listItem += '</button>';
|
46
71
|
this.serviceList.append(listItem);
|
47
72
|
}
|
@@ -52,18 +77,20 @@ class ConsulService {
|
|
52
77
|
var filter = new RegExp(e.target.value);
|
53
78
|
consulService.serviceList.children('button').each(function (){
|
54
79
|
if($(this).html().match(filter)) {
|
55
|
-
$(this).
|
56
|
-
|
80
|
+
var ui = $(this).closest( "button" )
|
81
|
+
ui.removeClass('d-none');
|
82
|
+
ui.addClass('d-block');
|
57
83
|
} else {
|
58
|
-
$(this).
|
59
|
-
|
84
|
+
var ui = $(this).closest( "button" )
|
85
|
+
ui.removeClass('d-block');
|
86
|
+
ui.addClass('d-none');
|
60
87
|
}
|
61
88
|
})
|
62
89
|
}
|
63
90
|
|
64
91
|
onClickServiceName(source) {
|
65
92
|
this.selectService(source);
|
66
|
-
this.updateURL();
|
93
|
+
this.updateURL($(source).find(".service-name").html());
|
67
94
|
}
|
68
95
|
|
69
96
|
onClickFilter(source) {
|
@@ -98,9 +125,11 @@ class ConsulService {
|
|
98
125
|
})
|
99
126
|
}
|
100
127
|
|
101
|
-
updateURL() {
|
128
|
+
updateURL(link) {
|
102
129
|
var newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
103
|
-
|
130
|
+
if (link) {
|
131
|
+
newUrl += '?service=' + link
|
132
|
+
}
|
104
133
|
window.history.pushState({},"",newUrl);
|
105
134
|
}
|
106
135
|
|
@@ -108,11 +137,10 @@ class ConsulService {
|
|
108
137
|
if (this.selectedService) {
|
109
138
|
$(this.selectedService).removeClass('active');
|
110
139
|
}
|
111
|
-
|
140
|
+
var serviceName = $(source).find(".service-name").html()
|
141
|
+
this.selectedService = source.closest( "button" );
|
112
142
|
$(this.selectedService).addClass('active');
|
113
143
|
|
114
|
-
var serviceName = $(source).html();
|
115
|
-
|
116
144
|
this.displayService(this.data.services[serviceName]);
|
117
145
|
}
|
118
146
|
|
@@ -120,7 +148,7 @@ class ConsulService {
|
|
120
148
|
$("#service-title").html(service['name']);
|
121
149
|
$("#instances-list").html("");
|
122
150
|
|
123
|
-
var serviceStatus =
|
151
|
+
var serviceStatus = buildServiceStatus(service);
|
124
152
|
|
125
153
|
for (var key in service['instances']) {
|
126
154
|
var instance = service['instances'][key];
|
@@ -132,21 +160,35 @@ class ConsulService {
|
|
132
160
|
serviceHtml.appendChild(checksStatusGenerator(instance));
|
133
161
|
var state = nodeState(instance);
|
134
162
|
serviceHtml.setAttribute('status', state);
|
135
|
-
serviceStatus[state] = (serviceStatus[state] || 0) + 1;
|
136
|
-
serviceStatus['total'] = (serviceStatus['total'] || 0) + 1;
|
137
|
-
|
138
163
|
$("#instances-list").append(serviceHtml);
|
139
164
|
}
|
140
165
|
|
141
166
|
$('#service-progress-passing').css('width', (serviceStatus['passing'] || 0) / serviceStatus['total'] * 100 + '%')
|
167
|
+
$('#service-progress-passing').html("passing (" + (serviceStatus['passing'] || 0) + ")")
|
142
168
|
$('#service-progress-warning').css('width', (serviceStatus['warning'] || 0) / serviceStatus['total'] * 100 + '%')
|
169
|
+
$('#service-progress-warning').html("warning (" + (serviceStatus['warning'] || 0) +")")
|
143
170
|
$('#service-progress-critical').css('width', (serviceStatus['critical'] || 0) / serviceStatus['total'] * 100 + '%')
|
171
|
+
$('#service-progress-critical').html("critical (" + (serviceStatus['critical'] || 0) + ")")
|
144
172
|
|
145
173
|
resizeWrapper('instances-wrapper', 'instances-list');
|
146
174
|
$('#instances-list .list-group-item').resize(resizeAll);
|
147
175
|
}
|
148
176
|
}
|
149
177
|
|
178
|
+
function buildServiceStatus(service) {
|
179
|
+
var serviceStatus = {};
|
180
|
+
|
181
|
+
for (var key in service['instances']) {
|
182
|
+
var instance = service['instances'][key];
|
183
|
+
var state = nodeState(instance);
|
184
|
+
|
185
|
+
serviceStatus[state] = (serviceStatus[state] || 0) + 1;
|
186
|
+
serviceStatus['total'] = (serviceStatus['total'] || 0) + 1;
|
187
|
+
}
|
188
|
+
|
189
|
+
return serviceStatus;
|
190
|
+
}
|
191
|
+
|
150
192
|
function nodeState(instance) {
|
151
193
|
status='passing';
|
152
194
|
for (var checkKey in instance.checks) {
|
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.1.
|
4
|
+
version: 1.1.2
|
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-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-http-request
|