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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f41bf7bc42201458abf40795cba80f42f871464d1c40a9e5617e109f37ee54d
4
- data.tar.gz: 6efd87a693e69e426c3c58fca95778a0d10ed07380c9d98cb62d9c69fcc11800
3
+ metadata.gz: feb7928f78cdbbfae6a96b7b6150c569addb523d94db80024c4493989cf1df4c
4
+ data.tar.gz: 93be5f37da47ebfefdfe40e836e28d0f5f440a5481da2db38c708c245d64769a
5
5
  SHA512:
6
- metadata.gz: bf254e910bb560f414d1740a09445f796c83ca3cf89a597940d8068c0ef717bd646cb5ef226c4e871661863e881c78d7dda63f473ef5c71310fb80151f225be1
7
- data.tar.gz: 416ee5c54b94a719fabd516355b0adc495ab3b80f351c75b8283a18a3ab73f8794e5081e6b9eab4d3f8a480cfae22732961fd3a938a9c1c10c2f2eaa7dc4d8fb
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,
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Async
3
- VERSION = '1.1.1'.freeze
3
+ VERSION = '1.1.2'.freeze
4
4
  end
5
5
  end
@@ -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
- instances: []
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
- this.selectService(nodes[i]);
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 service in this.data.services) {
43
- var listItem = '<button type="button" onclick="consulService.onClickServiceName(this)" class="list-group-item list-group-item-action">';
44
- listItem += service;
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).removeClass('d-none');
56
- $(this).addClass('d-block');
80
+ var ui = $(this).closest( "button" )
81
+ ui.removeClass('d-none');
82
+ ui.addClass('d-block');
57
83
  } else {
58
- $(this).removeClass('d-block');
59
- $(this).addClass('d-none');
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
- newUrl += '?service=' + $(this.selectedService).html();
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
- this.selectedService = source;
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.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-15 00:00:00.000000000 Z
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