jerakia 2.4.0 → 2.5.0
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/lib/jerakia/answer.rb +14 -4
- data/lib/jerakia/datasource.rb +9 -4
- data/lib/jerakia/datasource/consul_kv.rb +88 -0
- data/lib/jerakia/datasource/file.rb +2 -2
- data/lib/jerakia/datasource/http.rb +12 -3
- data/lib/jerakia/dsl/lookup.rb +0 -2
- data/lib/jerakia/policy.rb +1 -0
- data/lib/jerakia/response.rb +33 -8
- data/lib/jerakia/response/entry.rb +17 -0
- data/lib/jerakia/response/filter.rb +5 -1
- data/lib/jerakia/response/filter/dig.rb +25 -0
- data/lib/jerakia/server/rest.rb +2 -1
- data/lib/jerakia/util.rb +14 -0
- data/lib/jerakia/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e4145ea38aa8d6573c8511c06241c79032e38a1
|
4
|
+
data.tar.gz: d42e6335997192ff954540abf9e9930f35701217
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ae5b4c70dc8e34e1e486b89f297cae5772bfb138cfa057fbf040b393c00ba0dc65141f00b10e7c136fa6b0c3e2ad89b12dc47ecca0b8c9dd01cc6c6910c9fdd
|
7
|
+
data.tar.gz: 52cfaffb30597c12f0d4c881bd795239893ff6c1d49ec8ddb5aca03db9d8316404977e8eeb8ff28894f8ccdb69cbd7406350fca126c3b8433e85ade3ac873b10
|
data/lib/jerakia/answer.rb
CHANGED
@@ -10,6 +10,7 @@ class Jerakia
|
|
10
10
|
def initialize(lookup_type = :first, merge_strategy = :array)
|
11
11
|
@lookup_type = lookup_type
|
12
12
|
@merge_strategy = merge_strategy
|
13
|
+
@found = false
|
13
14
|
case lookup_type
|
14
15
|
when :first
|
15
16
|
@payload = nil
|
@@ -20,20 +21,29 @@ class Jerakia
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def process_response(response_entries)
|
23
|
-
response_entries.flatten.
|
24
|
+
responses = response_entries.flatten.compact
|
25
|
+
|
26
|
+
return nil if responses.empty?
|
27
|
+
@found = true
|
28
|
+
|
29
|
+
responses.each do |res|
|
24
30
|
case lookup_type
|
25
31
|
when :first
|
26
|
-
@payload = res
|
27
|
-
@datatype = res
|
32
|
+
@payload = res.value
|
33
|
+
@datatype = res.datatype
|
28
34
|
Jerakia.log.debug("Registered answer as #{payload}")
|
29
35
|
break
|
30
36
|
when :cascade
|
31
|
-
@payload << res
|
37
|
+
@payload << res.value
|
32
38
|
end
|
33
39
|
end
|
34
40
|
consolidate
|
35
41
|
end
|
36
42
|
|
43
|
+
def found?
|
44
|
+
@found
|
45
|
+
end
|
46
|
+
|
37
47
|
def consolidate
|
38
48
|
if lookup_type == :cascade && payload.is_a?(Array)
|
39
49
|
case merge_strategy
|
data/lib/jerakia/datasource.rb
CHANGED
@@ -15,9 +15,8 @@ class Jerakia
|
|
15
15
|
attr_reader :response
|
16
16
|
|
17
17
|
def initialize(lookup, opts)
|
18
|
-
self.class.validate_options(opts)
|
19
18
|
@response = Jerakia::Response.new(lookup)
|
20
|
-
@options = opts
|
19
|
+
@options = self.class.set_options(opts)
|
21
20
|
@request = lookup.request
|
22
21
|
@features = []
|
23
22
|
end
|
@@ -64,11 +63,17 @@ class Jerakia
|
|
64
63
|
opt
|
65
64
|
end
|
66
65
|
end
|
67
|
-
|
66
|
+
|
67
|
+
def self.set_options(args)
|
68
|
+
opts = {}
|
68
69
|
options.keys.each do |k|
|
69
|
-
options[k].call(args[k])
|
70
|
+
opts[k] = options[k].call(args[k])
|
70
71
|
end
|
72
|
+
validate_options(args)
|
73
|
+
opts
|
74
|
+
end
|
71
75
|
|
76
|
+
def self.validate_options(args)
|
72
77
|
args.keys.each do |k|
|
73
78
|
raise Jerakia::DatasourceArgumentError, "Unknown option #{k}" unless options.keys.include?(k)
|
74
79
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'diplomat'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
class Jerakia::Datasource::Consul_kv < Jerakia::Datasource::Instance
|
5
|
+
|
6
|
+
# datacenter option sets the :dc method in the Diplomat
|
7
|
+
# request to perform a consul lookup using a particular
|
8
|
+
# datacenter
|
9
|
+
#
|
10
|
+
option(:datacenter) { |str| str.is_a?(String) }
|
11
|
+
|
12
|
+
# to_hash, when used with recursive, will consolidate the
|
13
|
+
# results into a hash, instead of an array
|
14
|
+
#
|
15
|
+
option(:to_hash, :default => true) { |opt|
|
16
|
+
[ TrueClass, FalseClass ].include?(opt.class)
|
17
|
+
}
|
18
|
+
|
19
|
+
# Recursive will return the entire data structure from console
|
20
|
+
# rather than just the requested key
|
21
|
+
#
|
22
|
+
option(:recursive, :default => false) { |opt|
|
23
|
+
[ TrueClass, FalseClass ].include?(opt.class)
|
24
|
+
}
|
25
|
+
|
26
|
+
# The searchpath is the root path of the request, which will
|
27
|
+
# get appended with the namespace, and key if applicable.
|
28
|
+
# We allow this option to be ommited in case the lookup path
|
29
|
+
# starts at the namesapce.
|
30
|
+
#
|
31
|
+
option(:searchpath, :default => ['']) { |opt| opt.is_a?(Array) }
|
32
|
+
|
33
|
+
# Set any consul parameters against the Diplomat class
|
34
|
+
#
|
35
|
+
# These values are set in jerakia.yaml and are loaded directly
|
36
|
+
# to the class when we load the datasource for the first time.
|
37
|
+
#
|
38
|
+
consul_config = Jerakia.config['consul']
|
39
|
+
if consul_config.is_a?(Hash)
|
40
|
+
Diplomat.configure do |config|
|
41
|
+
config.url = consul_config['url'] if consul_config.has_key?('url')
|
42
|
+
config.acl_token = consul_config['acl_token'] if consul_config.has_key?('acl_token')
|
43
|
+
config.options = consul_config['options'] if consul_config['options'].is_a?(Hash)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
# Entrypoint for Jerakia lookups starts here.
|
50
|
+
#
|
51
|
+
def lookup
|
52
|
+
|
53
|
+
Jerakia.log.debug("[datasource::console_kv] backend performing lookup for #{request.key}")
|
54
|
+
paths = options[:searchpath].reject { |p| p.nil? }
|
55
|
+
|
56
|
+
key = request.key
|
57
|
+
namespace = request.namespace
|
58
|
+
|
59
|
+
|
60
|
+
answer do |response|
|
61
|
+
|
62
|
+
break if paths.empty?
|
63
|
+
path = paths.shift.split('/').compact
|
64
|
+
|
65
|
+
|
66
|
+
path << namespace
|
67
|
+
path << key unless key.nil?
|
68
|
+
|
69
|
+
diplomat_options = {
|
70
|
+
:recurse => options[:recursive],
|
71
|
+
:convert_to_hash => options[:to_hash],
|
72
|
+
:dc => options[:datacenter],
|
73
|
+
}
|
74
|
+
|
75
|
+
begin
|
76
|
+
key_path = path.flatten.join('/')
|
77
|
+
Jerakia.log.debug("[datasource::consul_kv] Looking up #{key_path} with options #{diplomat_options}")
|
78
|
+
result = Diplomat::Kv.get(key_path, diplomat_options)
|
79
|
+
rescue Diplomat::KeyNotFound => e
|
80
|
+
Jerakia.log.debug("NotFound encountered, skipping to next path entry")
|
81
|
+
next
|
82
|
+
rescue Faraday::ConnectionFailed => e
|
83
|
+
raise Jerakia::Error, "Failed to connect to consul service: #{e.message}"
|
84
|
+
end
|
85
|
+
response.submit result
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -8,7 +8,7 @@ class Jerakia::Datasource::File < Jerakia::Datasource::Instance
|
|
8
8
|
|
9
9
|
option :format, :default => :yaml
|
10
10
|
option :docroot, :default => '/var/lib/jerakia/data'
|
11
|
-
option :
|
11
|
+
option :extension
|
12
12
|
option :enable_caching, :default => true
|
13
13
|
|
14
14
|
def load_format_handler
|
@@ -88,7 +88,7 @@ class Jerakia::Datasource::File < Jerakia::Datasource::Instance
|
|
88
88
|
path = paths.shift
|
89
89
|
break unless path
|
90
90
|
data = read_from_file(path)
|
91
|
-
|
91
|
+
if data.has_key?(request.key)
|
92
92
|
response.submit data[request.key]
|
93
93
|
end
|
94
94
|
end
|
@@ -19,6 +19,14 @@ class Jerakia::Datasource::Http < Jerakia::Datasource::Instance
|
|
19
19
|
option :http_connect_timeout, :type => Integer
|
20
20
|
option :paths, :type => Array, :required => true
|
21
21
|
|
22
|
+
# When lookup_key is set to false, the datasource will not attempt to
|
23
|
+
# look up the key from a hash that gets returned. This flag will be
|
24
|
+
# set to default of false in Jerakia 3.0
|
25
|
+
#
|
26
|
+
option(:lookup_key, :default => true) { |opt|
|
27
|
+
[TrueClass,FalseClass].include?(opt.class)
|
28
|
+
}
|
29
|
+
|
22
30
|
def lookup
|
23
31
|
|
24
32
|
lookup_supported_params = [
|
@@ -53,9 +61,10 @@ class Jerakia::Datasource::Http < Jerakia::Datasource::Instance
|
|
53
61
|
Jerakia.log.debug("Datasource provided #{data} (#{data.class}) looking for key #{request.key}")
|
54
62
|
|
55
63
|
if data.is_a?(Hash)
|
56
|
-
|
57
|
-
|
58
|
-
|
64
|
+
if options[:lookup_key]
|
65
|
+
response.submit data[request.key] if data.has_key?(request.key)
|
66
|
+
else
|
67
|
+
response.submit data
|
59
68
|
end
|
60
69
|
else
|
61
70
|
unless options[:output] == 'plain' || options[:failure] == 'graceful'
|
data/lib/jerakia/dsl/lookup.rb
CHANGED
@@ -21,8 +21,6 @@ class Jerakia
|
|
21
21
|
# @api: public
|
22
22
|
def datasource(name, opts = {})
|
23
23
|
lookup.datasource = { :name => name, :opts => opts }
|
24
|
-
#datasource = Jerakia::Datasource.new(name, lookup, opts)
|
25
|
-
#lookup.datasource = datasource
|
26
24
|
end
|
27
25
|
|
28
26
|
# pass through exposed functions from the main lookup object
|
data/lib/jerakia/policy.rb
CHANGED
data/lib/jerakia/response.rb
CHANGED
@@ -1,7 +1,30 @@
|
|
1
1
|
class Jerakia::Response < Jerakia
|
2
|
-
attr_accessor :entries
|
3
2
|
attr_reader :lookup
|
4
3
|
|
4
|
+
class Entry
|
5
|
+
attr_reader :value
|
6
|
+
attr_reader :datatype
|
7
|
+
attr_reader :valid
|
8
|
+
|
9
|
+
def initialize(val)
|
10
|
+
@valid = true
|
11
|
+
set_value(val)
|
12
|
+
end
|
13
|
+
|
14
|
+
def invalidate
|
15
|
+
@valid = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid?
|
19
|
+
@valid
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_value(val)
|
23
|
+
@value = val
|
24
|
+
@datatype = val.class.to_s.downcase
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
5
28
|
def initialize(lookup)
|
6
29
|
@entries = []
|
7
30
|
@lookup = lookup
|
@@ -17,28 +40,30 @@ class Jerakia::Response < Jerakia
|
|
17
40
|
end
|
18
41
|
end
|
19
42
|
|
43
|
+
|
20
44
|
def submit(val)
|
21
45
|
Jerakia.log.debug "Backend submitted #{val}"
|
22
46
|
if want?
|
23
|
-
@entries <<
|
24
|
-
:value => val,
|
25
|
-
:datatype => val.class.to_s.downcase
|
26
|
-
}
|
47
|
+
@entries << Jerakia::Response::Entry.new(val)
|
27
48
|
Jerakia.log.debug "Added answer #{val}"
|
28
49
|
else
|
29
50
|
no_more_answers
|
30
51
|
end
|
31
52
|
end
|
32
53
|
|
33
|
-
def
|
34
|
-
|
54
|
+
def responses
|
55
|
+
@entries.each do |entry|
|
35
56
|
yield entry
|
36
57
|
end
|
37
58
|
end
|
38
59
|
|
60
|
+
def entries
|
61
|
+
@entries.select { |e| e.valid? }
|
62
|
+
end
|
63
|
+
|
39
64
|
def parse_values
|
40
65
|
@entries.map! do |entry|
|
41
|
-
Jerakia::Util.walk(entry
|
66
|
+
Jerakia::Util.walk(entry.value) do |v|
|
42
67
|
yield v
|
43
68
|
end
|
44
69
|
entry
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#class Jerakia::Response
|
2
|
+
# class Entry
|
3
|
+
#
|
4
|
+
# attr_reader :value
|
5
|
+
# attr_reader :datatype
|
6
|
+
#
|
7
|
+
# def initialize(val)
|
8
|
+
# set_value(val)
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def set_value(val)
|
12
|
+
# @value = val
|
13
|
+
# @datatype = val.class.to_s.downcase
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#end
|
17
|
+
#
|
@@ -1,10 +1,14 @@
|
|
1
1
|
class Jerakia::Response
|
2
2
|
module Filter
|
3
3
|
def filter!(name, opts = {})
|
4
|
+
|
5
|
+
unless opts.is_a?(Hash) || opts.is_a?(Array)
|
6
|
+
raise Jerakia::PolicyError, "Output filters may only accept hashes or arrays as arguments"
|
7
|
+
end
|
4
8
|
Jerakia::Util.autoload('response/filter', name)
|
5
9
|
Jerakia.log.debug("Invoking output filter #{name}")
|
6
10
|
instance_eval "extend Jerakia::Response::Filter::#{name.to_s.capitalize}"
|
7
|
-
instance_eval "self.filter_#{name}
|
11
|
+
instance_eval "self.filter_#{name}(#{opts})"
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Jerakia::Response
|
2
|
+
module Filter
|
3
|
+
module Dig
|
4
|
+
def filter_dig(path = [])
|
5
|
+
raise Jerakia::PolicyError, "Argument to output filter dig must be an array" unless path.is_a?(Array)
|
6
|
+
Jerakia.log.debug("[output_filter:dig]: Attempting to dig using path #{path}")
|
7
|
+
responses do |entry|
|
8
|
+
|
9
|
+
unless entry.value.is_a?(Hash)
|
10
|
+
raise Jerakia::Error, "Cannot perform dig on a non hash value"
|
11
|
+
end
|
12
|
+
|
13
|
+
value = Jerakia::Util.dig(entry.value, path.flatten)
|
14
|
+
if value == :not_found
|
15
|
+
Jerakia.log.debug('[output_filter:dig]: Digging value from response failed, invalidating')
|
16
|
+
entry.invalidate
|
17
|
+
else
|
18
|
+
entry.set_value(value)
|
19
|
+
Jerakia.log.debug("[output_filter:dig]: Re-submitting response as #{value}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/jerakia/server/rest.rb
CHANGED
data/lib/jerakia/util.rb
CHANGED
@@ -6,6 +6,20 @@ class Jerakia
|
|
6
6
|
require "jerakia/#{path}/#{mod}"
|
7
7
|
end
|
8
8
|
|
9
|
+
def dig(data, dig_path)
|
10
|
+
key = dig_path.shift
|
11
|
+
if dig_path.empty?
|
12
|
+
if data.has_key?(key)
|
13
|
+
return data[key]
|
14
|
+
else
|
15
|
+
return :not_found
|
16
|
+
end
|
17
|
+
else
|
18
|
+
return :not_found unless data[key].is_a?(Hash)
|
19
|
+
return dig(data[key], dig_path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
9
23
|
def walk(data)
|
10
24
|
if data.is_a?(Hash)
|
11
25
|
walk_hash(data) do |target|
|
data/lib/jerakia/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jerakia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Craig Dunn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '1.1'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: diplomat
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.0'
|
125
139
|
description: Extendable and flexible data lookup system
|
126
140
|
email:
|
127
141
|
executables:
|
@@ -143,6 +157,7 @@ files:
|
|
143
157
|
- lib/jerakia/cli/token.rb
|
144
158
|
- lib/jerakia/config.rb
|
145
159
|
- lib/jerakia/datasource.rb
|
160
|
+
- lib/jerakia/datasource/consul_kv.rb
|
146
161
|
- lib/jerakia/datasource/dummy.rb
|
147
162
|
- lib/jerakia/datasource/file.rb
|
148
163
|
- lib/jerakia/datasource/file/json.rb
|
@@ -163,7 +178,9 @@ files:
|
|
163
178
|
- lib/jerakia/policy.rb
|
164
179
|
- lib/jerakia/request.rb
|
165
180
|
- lib/jerakia/response.rb
|
181
|
+
- lib/jerakia/response/entry.rb
|
166
182
|
- lib/jerakia/response/filter.rb
|
183
|
+
- lib/jerakia/response/filter/dig.rb
|
167
184
|
- lib/jerakia/response/filter/encryption.rb
|
168
185
|
- lib/jerakia/response/filter/strsub.rb
|
169
186
|
- lib/jerakia/schema.rb
|