consul-templaterb 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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: