jerakia 2.4.0 → 2.5.0

This diff has not been reviewed by any users.
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
  SHA1:
3
- metadata.gz: ea3f9b99ad3814fc4868f19d64d8f47adf16e940
4
- data.tar.gz: 0ff66c99cdff190f8047dfce865cc01e749efa19
3
+ metadata.gz: 6e4145ea38aa8d6573c8511c06241c79032e38a1
4
+ data.tar.gz: d42e6335997192ff954540abf9e9930f35701217
5
5
  SHA512:
6
- metadata.gz: 1e291ef9b8af754741a04088d6782d1710d2194da4aedc73ddd6a447078e06ad119afca6c338080683300aa2e89be8adea381dba91468790acbcb5ccc97977d9
7
- data.tar.gz: 1ffc73296862825e61e8e6eb5ec6c46d6b31b27ce9d47150783879bf4e15762692b9b42fbff07401dd4e15c87aefbb5d84c8c3e53a7bf997ad29af01292e41ff
6
+ metadata.gz: 7ae5b4c70dc8e34e1e486b89f297cae5772bfb138cfa057fbf040b393c00ba0dc65141f00b10e7c136fa6b0c3e2ad89b12dc47ecca0b8c9dd01cc6c6910c9fdd
7
+ data.tar.gz: 52cfaffb30597c12f0d4c881bd795239893ff6c1d49ec8ddb5aca03db9d8316404977e8eeb8ff28894f8ccdb69cbd7406350fca126c3b8433e85ade3ac873b10
@@ -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.each do |res|
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[:value]
27
- @datatype = res[:datatype]
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[:value]
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
@@ -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
- def self.validate_options(args)
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 :extention
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
- unless data[request.key].nil?
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
- unless data[request.key].nil?
57
- Jerakia.log.debug("Found data #{data[request.key]}")
58
- response.submit data[request.key]
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'
@@ -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
@@ -44,6 +44,7 @@ class Jerakia
44
44
  break unless lookup_instance.proceed?
45
45
  end
46
46
  answer.process_response(response_entries)
47
+ Jerakia.log.debug(answer)
47
48
  return answer
48
49
  end
49
50
 
@@ -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 values
34
- Jerakia::Util.walk(@entries) do |entry|
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[:value]) do |v|
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} (#{opts})"
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
@@ -123,7 +123,8 @@ class Jerakia
123
123
  rescue Jerakia::Error => e
124
124
  request_failed(e.message, 501)
125
125
  end
126
- encode_result({ :status => 'ok',
126
+ encode_result({ :status => 'ok',
127
+ :found => answer.found?,
127
128
  :payload => answer.payload})
128
129
  end
129
130
 
@@ -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|
@@ -3,5 +3,5 @@ class Jerakia
3
3
  #
4
4
  # This should be updated when a new gem is released and it is read from the gemspec file
5
5
  #
6
- VERSION = '2.4.0'.freeze
6
+ VERSION = '2.5.0'.freeze
7
7
  end
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.0
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: 2017-08-14 00:00:00.000000000 Z
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