consul-templaterb 1.0.8 → 1.0.9

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: 49568fc4a6f043e390484820ea383914a31d35c99149669a4b77772bfeed0504
4
- data.tar.gz: f56e6cd3882cb1154219c3c56da2ae9b484e9c6196c685980c296e713c6f9650
3
+ metadata.gz: 0d408d6a635426874369831aa3c7f12890ebec2c7b5bb7d571b76bdbef9da041
4
+ data.tar.gz: 93af5f9b70790a9c9665bea3d13ae3d6322f7a3b5ff703d132a890cdc37ed6f6
5
5
  SHA512:
6
- metadata.gz: 7e241be76b837635ef83dff4ec76191bba016cdb7e040b4c17325458465d6b10ae5a8430527484be30a2b0bf05d0a86350e970742b570766d14578a621f817fb
7
- data.tar.gz: 9f4ccd3d0222a28abf6bcb89b46e101c627d736c73b6451a39f9bb4507e68713b1a88abfaf66d4e5a152de09d84b55ac486af2f2a692967a26762bb62129fd84
6
+ metadata.gz: 2237575069b92c50374adc5f91587f1737f0cf42a634acb9b469b6cc076175dbdb48e8d944df8de91ccf8b5ebaf089dca4cdb088d4cb46fe07fcb2dbebbabf54
7
+ data.tar.gz: 7ad73644600bc5130306c2a9190e092ae59ca08a529e75097b26da91907353a2a50d17fb249a040f8758856917463f035372fb5899728c8ae7f03630b1ee6895
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
+ # CHANGELOG
2
+
1
3
  ## (UNRELEASED)
2
4
 
5
+ IMPROVEMENTS:
6
+
7
+ ## 1.0.8 (March 18, 2018)
8
+
9
+ IMPROVEMENTS:
10
+
11
+ * Added [samples/sample_keys.html.erb](samples/sample_keys.html.erb)
12
+ * When `get_value_json` is called, allow to catch silently errors
13
+ * Nicer error messages when templates are invalid with exact line of error
14
+ * Added optional params_file to `--template` flag to create parameters for templates
15
+ * Documentation improvements
16
+
3
17
  ## 1.0.8 (March 18, 2018)
4
18
 
5
19
  IMPROVEMENTS:
@@ -10,7 +24,7 @@ IMPROVEMENTS:
10
24
  * Added optional parameters to sub-template in `render_file`
11
25
  * Added `param(name, default_value)` to retrieve parameter from sub-template
12
26
  * Use `CONSUL_HTTP_TOKEN` if present in environment variables to get the token
13
- * Added [TemplateAPI.md](TemplateAPI.md] for documenting functions
27
+ * Added [TemplateAPI.md](TemplateAPI.md) for documenting functions
14
28
 
15
29
  ## 1.0.7 (March 16, 2018)
16
30
 
@@ -37,7 +51,7 @@ IMPROVEMENTS:
37
51
 
38
52
  BUG FIXES:
39
53
 
40
- * fixed default value for parameter -c to http://localhost:8500
54
+ * fixed default value for parameter -c to `http://localhost:8500`
41
55
 
42
56
  ## 1.0.4 (March 12, 2018)
43
57
 
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # consul-templaterb [![Build Status](https://api.travis-ci.org/criteo/consul-templaterb.svg?branch=master)](https://travis-ci.org/criteo/consul-templaterb)
1
+ # consul-templaterb
2
+
3
+ [![Build Status](https://api.travis-ci.org/criteo/consul-templaterb.svg?branch=master)](https://travis-ci.org/criteo/consul-templaterb)
4
+ [![Gem Version](https://badge.fury.io/rb/consul-templaterb.svg)](http://github.com/criteo/consul-templaterb/releases)
5
+ [![License](https://img.shields.io/badge/license-ApacheV2-yellowgreen.svg)](#license)
2
6
 
3
7
  The ruby GEM [consul-templaterb](https://rubygems.org/gems/consul-templaterb)
4
8
  is both a library and an executable that allows to generate files
@@ -58,7 +62,7 @@ Compared to consul-template, consul-templaterb offers the following features:
58
62
  The executable supports semantics and command line flags and options similar to
59
63
  HashiCorp's Consul-template, so many flags you might use in consul-template will
60
64
  work in a similar way. It also supports the same environment variable
61
- `CONSUL_HTTP_ADDR` to find the Consul Agent to query and 'CONSUL_HTTP_TOKEN' to
65
+ `CONSUL_HTTP_ADDR` to find the Consul Agent to query and `CONSUL_HTTP_TOKEN` to
62
66
  get the token.
63
67
 
64
68
  ## Installation
@@ -128,7 +132,7 @@ templates or write your owns, it is very easy!
128
132
 
129
133
  ```shell
130
134
  $ consul-templaterb --help
131
- USAGE: bin/consul-templaterb [[options]]
135
+ USAGE: consul-templaterb [[options]]
132
136
  -h, --help Show help
133
137
  -v, --version Show Version
134
138
  -c, --consul-addr=<address> Address of Consul, eg: http://localhost:8500
@@ -136,12 +140,12 @@ USAGE: bin/consul-templaterb [[options]]
136
140
  -w, --wait=<min_duration> Wait at least n seconds before each template generation
137
141
  -r, --retry-delay=<min_duration> Min Retry delay on Error/Missing Consul Index
138
142
  -k, --hot-reload=<behavior> Control hot reload behaviour, one of :[die (kill daemon on hot reload failure), keep (on error, keep running), disable (hot reload disabled)]
139
- -K, --sig-term=kill_signal Signal to sent to next --exec command on kill, default=#{cur_sig_term}
140
- -R, --sig-reload=reload_signal Signal to sent to next --exec command on reload (NONE supported), default=#{cur_sig_reload}
143
+ -K, --sig-term=kill_signal Signal to sent to next --exec command on kill, default=TERM
144
+ -R, --sig-reload=reload_signal Signal to sent to next --exec command on reload (NONE supported), default=HUP
141
145
  -e, --exec=<command> Execute the following command
142
146
  -d, --debug-network-usage Debug the network usage
143
- -t erb_file:[output]:[command], Add a erb template, its output and optional reload command
144
- --template
147
+ -t erb_file:[output]:[command]:[params_file],
148
+ --template Add a erb template, its output and optional reload command
145
149
  --once Do not run the process as a daemon
146
150
  ```
147
151
 
@@ -156,12 +160,15 @@ if the `--template my_file.ext.erb:myfile.ext` was used.
156
160
  ### Generate multiple templates
157
161
 
158
162
  In the same way as consul-template, consul-templaterb supports multiple templates and executing
159
- commands when the files do change. The parameter `--template <ERB>:<DEST>:[reload_command]` works
163
+ commands when the files do change. The parameter `--template <ERB>:<DEST>:[reload_command]:params_file` works
160
164
  in the following way:
161
165
 
162
166
  * ERB : the ERB file to use as a template
163
167
  * DEST: the destination file
164
168
  * reload_command: optional shell command executed whenever the file has been modified
169
+ * params_file: JSON or YAML file to load and to use as parameter for template (see
170
+ [param() function](TemplateAPI.md#paramparameter_name-default_value-nil) to retrieve
171
+ the values)
165
172
 
166
173
  The argument can be specified multiple times, ex:
167
174
 
data/TemplateAPI.md CHANGED
@@ -1,9 +1,10 @@
1
- # Template API for writting templates
1
+ # Template API for writing templates
2
2
 
3
3
  Here are the various functions you might use in your templates.
4
4
 
5
- For each function, mandatory arguments are specified at the beginning while optional ones are marked with `[]`.
6
- Most of them support the optional dc attribute to access data from another datacenter. If the `dc`
5
+ For each function, documentation specifies mandatory arguments at the beginning while optional ones are
6
+ annoted with `[]`.
7
+ Most of them support the optional dc attribute to use data from another datacenter. If the `dc`
7
8
  attribute is not specified, the function will output data from the current datacenter.
8
9
 
9
10
  To ease template development, `consul-templaterb` supports HOT reload of templates, thus it is possible to
@@ -43,11 +44,78 @@ name or its ID. If DC is specified, will lookup for given node in another datace
43
44
 
44
45
  [Find all the checks](https://www.consul.io/api/health.html#list-checks-for-service) of a given service.
45
46
 
46
- ## kv(name = nil, dc: nil, keys: nil, recurse: false)
47
+ ## kv(name, [dc: nil], [keys: false], [recurse: false])
47
48
 
48
49
  [Read keys from KV Store](https://www.consul.io/api/kv.html#read-key). It can be used for both listing the keys and
49
50
  getting the values. See the file in samples [keys.html.erb](samples/keys.html.erb) for a working example.
50
51
 
52
+ Variants:
53
+
54
+ * no additional parameter: will only retrieve the key you asked for
55
+ * `keys: true` : will retrieve the hierarchy of keys, but without the values, useful if values might be large, in
56
+ order to perform simple listings
57
+ * `recurse: true`: will retrieve all hierarchy of keys with their values
58
+
59
+ Please have a look at [samples/sample_keys.html.erb](samples/sample_keys.html.erb) for examples on how using it.
60
+
61
+ ### Using the result of kv
62
+
63
+ Since KV has several modes, it depends whether you asked for one or several keys.
64
+
65
+ Thus, we recommend using a helper to get the value (while you might use it directly).
66
+
67
+ In order to ease the use, 3 helpers are available and all have a optional argument `path`. When path is specified
68
+ and the call is retrieving several keys, it allows to select a specific one.The available helpers are the following:
69
+
70
+ * `get_value( [path] )` : Get a raw value
71
+ * `get_value_decoded( [path] )` : Get the value decoded from Base64
72
+ * `get_value_json( [path], [catch_errors: true] )` : when your payload is JSON,
73
+ decode Base64 first and then decode the JSON. If catch_errors is set to true,
74
+ if will not throw an error during rendering of template and return nil. Otherwise
75
+ an Error will be thrown and have to be catch if you are unsure if the value is valid
76
+ JSON
77
+
78
+ #### Get the result of a single value
79
+
80
+ The easiest, use the helpers to retrieve the values in the following formats:
81
+
82
+ * `kv('/my/path/to/value').get_value` : get the raw value of a single key in KV
83
+ * `kv('/my/path/to/value').get_decoded` : get the decoded value of a single key in KV
84
+ * `kv('/my/path/to/value').get_value_json` : get the base64 decoded value and try decoding it as JSON
85
+
86
+ #### Iterate over values
87
+
88
+ If you want to iterate amongst all values, you might to it that way:
89
+
90
+ ```erb
91
+ <%
92
+ kv('/my/multiple/values', recurse: true).each do |tuple|
93
+ key = tuple['Key']
94
+ value_decoded = Base64.decode64(tuple['Value'])
95
+ %>
96
+ <div>Decoded value: <%= value_decoded %>
97
+ <div>JSON value: <%= JSON.parse( value_decoded ) %>
98
+ <%
99
+ end
100
+ %>
101
+ ```
102
+
103
+ #### Fetch all values at once, but interrested only by a few
104
+
105
+ When using `kv('/my/multiple/values', recurse: true)`, only a single call is performed, thus,
106
+ it is far more efficient to retrive multiple values from the KV under the same root. Thus,
107
+ in order to display several discreet values, it is possible to do the following:
108
+
109
+ ```erb
110
+ result = kv('/my/multiple/values', recurse: true)
111
+ value1 : <%= result.get_decoded('/my/multiple/values/value1') %>
112
+ value42 : <%= result.get_decoded('/my/multiple/values/value42') %>
113
+ value123 : <%= result.get_decoded('/my/multiple/values/value123') %>
114
+ ```
115
+
116
+ Since `kv('/my/multiple/values', recurse: true)` will retrieve all values at once, it might be more
117
+ efficient in some cases than retrieving all values one by one.
118
+
51
119
  ## agent_metrics()
52
120
 
53
121
  [Get the metrics of Consul Agent](https://www.consul.io/api/agent.html#view-metrics). Since this endpoint does
@@ -81,4 +149,27 @@ the template using `param('title', 'My default Value')` in the `header.html.erb`
81
149
  Can be used within a template to access a parameter. Parameters can be specified with `render_file`
82
150
  directive. Optional value `default_value` allow to get a value if parameter has not been set.
83
151
 
84
- See [samples/common/header.html.erb](samples/common/header.html.erb) for example of usage.
152
+ It allows to create re-usable sub-templates that might be used in several places with several types
153
+ of parameters. Thus, templates can be called like kind of functions and generate output based on
154
+ the parameters provided.
155
+
156
+ Example:
157
+
158
+ ```erb
159
+ render_file('show_service.html.erb', {service_name: 'service1', title: 'My Nice Service'})
160
+ [...]
161
+ render_file('show_service.html.erb', {service_name: 'service2', title: 'My Nicer Service'})
162
+ ```
163
+
164
+ Note that you can also add parameters into a top level service using the command line:
165
+
166
+ ```sh
167
+ consul-templaterb --template "source.html.erb:dest.html:reload_command:params.yaml"
168
+ [...]
169
+ ```
170
+
171
+ In that case, it would load the content of params.yaml and inject it as params when evaluating
172
+ template `source.html.erb`. Injection of params using 4th parameter of `--template` supports
173
+ YAML as well as JSON format. Those parameter files are NOT automatically reloaded however.
174
+
175
+ See [samples/common/header.html.erb](samples/common/header.html.erb) for example of usage.
@@ -154,7 +154,7 @@ optparse = OptionParser.new do |opts|
154
154
  end
155
155
  end
156
156
 
157
- opts.on('-t', '--template erb_file:[output]:[command]', String, 'Add a erb template, its output and optional reload command') do |tpl|
157
+ opts.on('-t', '--template erb_file:[output]:[command]:[params_file]', String, 'Add a erb template, its output and optional reload command') do |tpl|
158
158
  splitted = tpl.split(':')
159
159
  source = splitted[0]
160
160
  dest = splitted[1]
@@ -164,7 +164,10 @@ optparse = OptionParser.new do |opts|
164
164
  end
165
165
  raise "Source and destination cannot be the same in #{tpl}" if source == dest || dest.empty?
166
166
  command = splitted[2]
167
- consul_engine.add_template(source, dest)
167
+ parameter_file = splitted[3]
168
+ params = {}
169
+ params = Consul::Async::Utilities.load_parameters_from_file(parameter_file) if parameter_file
170
+ consul_engine.add_template(source, dest, params)
168
171
 
169
172
  if command
170
173
  consul_engine.add_template_callback do |_all_ready, _template_manager, results|
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  end
27
27
  spec.bindir = 'bin'
28
28
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
29
- spec.extra_rdoc_files = ['README.md', 'TemplateAPI.md']
29
+ spec.extra_rdoc_files = ['README.md', 'CHANGELOG.md', 'TemplateAPI.md']
30
30
  spec.require_paths = ['lib']
31
31
 
32
32
  spec.require_paths = ['lib']
@@ -12,6 +12,13 @@ module Consul
12
12
  end
13
13
  end
14
14
 
15
+ class SyntaxErrorInTemplate < InvalidTemplateException
16
+ attr_reader :cause
17
+ def initialize(cause)
18
+ @cause = cause
19
+ end
20
+ end
21
+
15
22
  class ConsulEndPointsManager
16
23
  attr_reader :conf, :net_info, :start_time
17
24
  def initialize(consul_configuration)
@@ -126,6 +133,14 @@ module Consul
126
133
  render(File.read(new_path), new_path, params)
127
134
  end
128
135
 
136
+ def find_line(e)
137
+ return e.message.dup[5..-1] if e.message.start_with? '(erb):'
138
+ e.backtrace.each do |line|
139
+ return line[5..-1] if line.start_with? '(erb):'
140
+ end
141
+ nil
142
+ end
143
+
129
144
  def render(tpl, tpl_file_path, params = {})
130
145
  # Ugly, but allow to use render_file well to support stack of calls
131
146
  old_value = @context
@@ -138,11 +153,14 @@ module Consul
138
153
  result
139
154
  rescue StandardError => e
140
155
  e2 = InvalidTemplateException.new e
141
- raise e2, "Template contains errors: #{e.message}", e.backtrace
156
+ raise e2, "[TEMPLATE EVALUATION ERROR] #{tpl_file_path}#{find_line(e)}: #{e.message}"
157
+ rescue SyntaxError => e
158
+ e2 = SyntaxErrorInTemplate.new e
159
+ raise e2, "[TEMPLATE SYNTAX ERROR] #{tpl_file_path}#{find_line(e)}: #{e.message}"
142
160
  end
143
161
 
144
- def write(file, tpl, last_result, tpl_file_path)
145
- data = render(tpl, tpl_file_path)
162
+ def write(file, tpl, last_result, tpl_file_path, params = {})
163
+ data = render(tpl, tpl_file_path, params)
146
164
  not_ready = []
147
165
  ready = 0
148
166
  @iteration = Time.now.utc - @start_time
@@ -329,10 +347,15 @@ module Consul
329
347
  end
330
348
 
331
349
  # Helper to get the value decoded as JSON
332
- def get_value_json(name = root)
350
+ def get_value_json(name = root, catch_errors: true)
333
351
  x = get_value_decoded(name)
334
352
  return nil unless x
335
- JSON.parse(x)
353
+ begin
354
+ JSON.parse(x)
355
+ rescue JSON::ParserError => e
356
+ return nil if catch_errors
357
+ raise StandardError.new(e), "get_value_json() cannot deserialize kv(#{name}) as JSON: #{e.message}", e.backtrace
358
+ end
336
359
  end
337
360
  end
338
361
  end
@@ -21,17 +21,18 @@ module Consul
21
21
  @template_callbacks << block
22
22
  end
23
23
 
24
- def add_template(source, dest)
25
- @templates.push([source, dest])
24
+ def add_template(source, dest, params = {})
25
+ @templates.push([source, dest, params])
26
26
  end
27
27
 
28
28
  def run(template_manager)
29
29
  @template_manager = template_manager
30
30
  EventMachine.run do
31
31
  template_renders = []
32
- @templates.each do |template_file, output_file|
32
+ @templates.each do |template_file, output_file, params|
33
33
  template_renders << Consul::Async::ConsulTemplateRender.new(template_manager, template_file, output_file,
34
- hot_reload_failure: hot_reload_failure)
34
+ hot_reload_failure: hot_reload_failure,
35
+ params: params)
35
36
  end
36
37
  EventMachine.add_periodic_timer(1) do
37
38
  begin
@@ -49,6 +50,10 @@ module Consul
49
50
  STDERR.puts "[ERROR] callback error: #{cbk_error.inspect}"
50
51
  raise cbk_error
51
52
  end
53
+ rescue Consul::Async::InvalidTemplateException => e
54
+ STDERR.puts "[FATAL]#{e}"
55
+ template_manager.terminate
56
+ EventMachine.stop
52
57
  rescue StandardError => e
53
58
  STDERR.puts "[ERROR] Fatal error occured: #{e.inspect} - #{e.backtrace}"
54
59
  template_manager.terminate
@@ -20,8 +20,8 @@ module Consul
20
20
  end
21
21
  end
22
22
  class ConsulTemplateRender
23
- attr_reader :template_file, :output_file, :template_file_ctime, :hot_reload_failure
24
- def initialize(template_manager, template_file, output_file, hot_reload_failure: 'die')
23
+ attr_reader :template_file, :output_file, :template_file_ctime, :hot_reload_failure, :params
24
+ def initialize(template_manager, template_file, output_file, hot_reload_failure: 'die', params: {})
25
25
  @hot_reload_failure = hot_reload_failure
26
26
  @template_file = template_file
27
27
  @output_file = output_file
@@ -29,10 +29,11 @@ module Consul
29
29
  @last_result = ''
30
30
  @last_result = File.read(output_file) if File.exist? output_file
31
31
  @template = load_template
32
+ @params = params
32
33
  end
33
34
 
34
35
  def render(tpl = @template)
35
- @template_manager.render(tpl, template_file)
36
+ @template_manager.render(tpl, template_file, params)
36
37
  end
37
38
 
38
39
  def run
@@ -58,7 +59,7 @@ module Consul
58
59
  end
59
60
 
60
61
  def write
61
- success, modified, last_res = @template_manager.write(@output_file, @template, @last_result, template_file)
62
+ success, modified, last_res = @template_manager.write(@output_file, @template, @last_result, template_file, params)
62
63
  @last_result = last_res if last_res
63
64
  [success, modified, @last_result]
64
65
  end
@@ -70,7 +71,7 @@ module Consul
70
71
  @template_file_ctime = new_time
71
72
  return update_template(load_template)
72
73
  rescue Consul::Async::InvalidTemplateException => e
73
- STDERR.puts "****\n[ERROR] HOT Reload of template #{template_file} did fail due to #{e}\n****\n"
74
+ STDERR.puts "****\n[ERROR] HOT Reload of template #{template_file} did fail due to:\n #{e}\n****\n"
74
75
  raise e unless hot_reload_failure == 'keep'
75
76
  STDERR.puts "[WARN] Hot reload of #{template_file} was not taken into account, keep running with previous version"
76
77
  end
@@ -1,3 +1,6 @@
1
+ require 'tempfile'
2
+ require 'yaml'
3
+ require 'json'
1
4
  module Consul
2
5
  module Async
3
6
  class Utilities
@@ -12,6 +15,18 @@ module Consul
12
15
  "#{(bytes / 1_073_741_824.0).round(2)} Gb"
13
16
  end
14
17
  end
18
+
19
+ # Loads parameters from a file, supports JSON and YAML
20
+ def self.load_parameters_from_file(parameters_file)
21
+ raise "Parameters file #{parameters_file} does not exists" unless File.exist? parameters_file
22
+ if parameters_file.downcase.end_with?('.yaml', '.yml')
23
+ YAML.load_file(parameters_file)
24
+ elsif parameters_file.downcase.end_with?('.json')
25
+ JSON.parse(File.read(parameters_file))
26
+ else
27
+ raise "Don't know how to load parameters file #{parameters_file}: JSON and YAML supported"
28
+ end
29
+ end
15
30
  end
16
31
  end
17
32
  end
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Async
3
- VERSION = '1.0.8'.freeze
3
+ VERSION = '1.0.9'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,96 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
6
+ <meta name="description" content="Display Consul information"/>
7
+ <meta name="author" content="Criteo"/>
8
+ <meta http-equiv="refresh" content="<%= param('refresh', ENV['REFRESH'] || '10') %>"/>
9
+ <title>This page displays random K/V every 10 seconds %></title>
10
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
11
+ <style>
12
+ body {
13
+ padding-top: 5rem;
14
+ }
15
+ .check {
16
+ transition: opacity 1s ease-out;
17
+ }
18
+ </style>
19
+ <style id="css-states">
20
+ </style>
21
+ </head>
22
+ <body>
23
+ <main class="container">
24
+ <h1>Keys example</h1>
25
+ <div>
26
+ This example shows how to use kv() results. It requires at least one key if the Consul's KV in order to display something.
27
+ </div>
28
+ <%
29
+ result = kv('', keys:true)
30
+ num_keys = result.count
31
+ # We refresh key every 10 seconds only
32
+ key_index = (Time.now.to_i / 10)
33
+ prng = Random.new
34
+ if num_keys > 0
35
+ key_to_display = result[key_index % num_keys]
36
+ end
37
+ %>
38
+ <div>
39
+ <h2>Using a single key</h2>
40
+ <div>Found <%= num_keys %> keys in KV/Store</div>
41
+ <%
42
+ if key_to_display
43
+ %>
44
+ <h1>Display a random single key using helpers</h1>
45
+ <div>
46
+ <h3>kv('<%= key_to_display %>').get_value :</h3>
47
+ <pre><%= kv(key_to_display).get_value %></pre>
48
+ </div>
49
+ <div>
50
+ <h3>kv('<%= key_to_display %>').get_value_decoded</h3>
51
+ <pre><%=
52
+ ERB::Util.html_escape(kv(key_to_display).get_value_decoded)
53
+ %></pre>
54
+ </div>
55
+ <div>
56
+ <h3>kv('<%= key_to_display %>').get_value_json(catch_errors: true)</h3>
57
+ <code><%
58
+ # catch_errors: true will return nil if data cannot be converted to JSON
59
+ json = kv(key_to_display).get_value_json(catch_errors: true)
60
+ %><%= (json ? jERB::Util.html_escape(json) : 'No Valid JSON Data') %></code>
61
+ </div>
62
+ <%
63
+ end
64
+ %>
65
+ </div>
66
+ <div>
67
+ <h2>Listing all keys (without their values)</h2>
68
+ <ul>
69
+ <%
70
+ result.each do |key_name|
71
+ %>
72
+ <li><%= key_name %></li>
73
+ <%
74
+ end
75
+ %>
76
+ </ul>
77
+ </div>
78
+ <div>
79
+ <h2>Listing 10 first keys (with their values)</h2>
80
+ <ol>
81
+ <% kv_values = kv('', recurse: true)
82
+ index = 0
83
+ kv_values.each do |tuple|
84
+ index += 1
85
+ break if index > 10
86
+ key_name = tuple['Key']
87
+ %>
88
+ <li><%= key_name %>: <code><%= kv_values.get_value_decoded(key_name) %></code></li>
89
+ <%
90
+ end
91
+ %>
92
+ </ol>
93
+ </div>
94
+ </main>
95
+ </body>
96
+ </html>
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.0.8
4
+ version: 1.0.9
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-03-18 00:00:00.000000000 Z
11
+ date: 2018-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request
@@ -131,6 +131,7 @@ executables:
131
131
  extensions: []
132
132
  extra_rdoc_files:
133
133
  - README.md
134
+ - CHANGELOG.md
134
135
  - TemplateAPI.md
135
136
  files:
136
137
  - ".gitignore"
@@ -166,6 +167,7 @@ files:
166
167
  - samples/ha_proxy.cfg.erb
167
168
  - samples/keys.html.erb
168
169
  - samples/nodes.html.erb
170
+ - samples/sample_keys.html.erb
169
171
  - samples/services.html.erb
170
172
  homepage: https://rubygems.org/gems/consul-templaterb
171
173
  licenses: