jerakia 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/jerakia/log.rb CHANGED
@@ -2,12 +2,12 @@ class Jerakia::Log < Jerakia
2
2
  require 'logger'
3
3
  def initialize(level = :info, file = '/var/log/jerakia.log')
4
4
  begin
5
- @@logger ||= Logger.new(file)
5
+ @@logger = Logger.new(file)
6
6
  rescue Errno::EACCES => e
7
7
  raise Jerakia::Error, "Error opening log file, #{e.message}"
8
8
  end
9
9
 
10
- @@level ||= level
10
+ @@level = level
11
11
  case @@level
12
12
  when :verbose
13
13
  @@logger.level = Logger::INFO
@@ -42,20 +42,4 @@ class Jerakia::Log < Jerakia
42
42
  @@logger.fatal msg
43
43
  end
44
44
 
45
- # def self.fatal(msg)
46
- # self.new.fatal msg
47
- # end
48
- #
49
- # def self.error(msg)
50
- # self.new.error msg
51
- # end
52
- #
53
- # def self.debug(msg)
54
- # self.new.debug msg
55
- # end
56
- #
57
- ## def self.info(msg)
58
- # puts @@logger
59
- # self.new.info msg
60
- # end
61
45
  end
@@ -14,7 +14,6 @@ class Jerakia::Lookup
14
14
  attr_reader :output_filters
15
15
  attr_reader :name
16
16
  attr_reader :pluginfactory
17
- attr_reader :datasource
18
17
 
19
18
  def initialize(name, opts, req, scope)
20
19
  @name = name
@@ -58,18 +57,6 @@ class Jerakia::Lookup
58
57
  pluginfactory
59
58
  end
60
59
 
61
- def get_datasource
62
- @datasource
63
- end
64
-
65
- def datasource(source, opts = {})
66
- @datasource = Jerakia::Datasource.new(source, self, opts)
67
- end
68
-
69
- # If set, Jerakia will pass each Jerakia::Response object
70
- # to an output filter plugin
71
- #
72
-
73
60
  def scope
74
61
  scope_object.value
75
62
  end
@@ -131,15 +118,4 @@ class Jerakia::Lookup
131
118
  end
132
119
  end
133
120
 
134
- def run
135
- Jerakia.log.verbose("lookup: #{@name} key: #{@request.key} namespace: #{@request.namespace.join('/')}")
136
- @datasource.run
137
- response = @datasource.response
138
- @output_filters.each do |filter|
139
- response.filter! filter[:name], filter[:opts]
140
- end
141
- response
142
- end
143
-
144
- private
145
121
  end
@@ -1,85 +1,58 @@
1
1
  require 'jerakia/launcher'
2
2
  require 'jerakia/answer'
3
3
  require 'jerakia/schema'
4
+ require 'jerakia/datasource'
4
5
 
5
6
  class Jerakia
6
7
  class Policy
7
8
  attr_accessor :lookups
8
- attr_reader :answer
9
- attr_reader :scope
10
- attr_reader :lookup_proceed
11
- attr_reader :schema
12
- attr_reader :request
9
+ attr_reader :name
10
+ attr_reader :datasources
13
11
 
14
12
  # _opts currently does not get used, but is included here as a placeholder
15
13
  # for allowing policies to be declared with options;
16
14
  # policy :foo, :option => :value do
17
15
  #
18
- def initialize(_name, _opts, req)
19
- if req.use_schema && Jerakia.config[:enable_schema]
20
- schema_config = Jerakia.config[:schema] || {}
21
- @schema = Jerakia::Schema.new(req, schema_config)
22
- end
23
-
16
+ def initialize(name, _opts)
17
+ @name = name
24
18
  @lookups = []
25
- @request = req
26
- @answer = Jerakia::Answer.new(req.lookup_type)
27
- @scope = Jerakia::Scope.new(req)
28
- @lookup_proceed = true
19
+ @datasources = {}
29
20
  end
30
21
 
31
- def clone_request
32
- Marshal.load(Marshal.dump(request))
33
- end
22
+ def run(request)
34
23
 
35
- def submit_lookup(lookup)
36
- raise Jerakia::PolicyError, "Lookup #{lookup.name} has no datasource defined" unless lookup.get_datasource
37
- @lookups << lookup if lookup.valid? && @lookup_proceed
38
- @lookup_proceed = false if !lookup.proceed? && lookup.valid?
39
- end
24
+ if request.use_schema && Jerakia.config[:enable_schema]
25
+ schema_config = Jerakia.config[:schema] || {}
26
+ @schema = Jerakia::Schema.new(request, schema_config)
27
+ end
40
28
 
41
- def execute
42
- response_entries = []
29
+ scope = Jerakia::Scope.new(request)
30
+ answer = Jerakia::Answer.new(request.lookup_type, request.merge)
43
31
 
44
- @lookups.each do |l|
45
- responses = l.run
46
- lookup_answers = responses.entries.map { |r| r }
32
+ response_entries = []
33
+ lookups.each do |lookup|
34
+ lookup_instance = lookup.call clone_request(request), scope
35
+ next unless lookup_instance.valid? && lookup_instance.proceed?
36
+ register_datasource lookup_instance.datasource[:name]
37
+ responses = Jerakia::Datasource.run(lookup_instance)
38
+ lookup_instance.output_filters.each do |filter|
39
+ Jerakia.log.debug("Using output filter #{filter[:name]}")
40
+ responses.filter! filter[:name], filter[:opts]
41
+ end
42
+ lookup_answers = responses.entries.map { |r| r}
47
43
  response_entries << lookup_answers if lookup_answers
48
44
  end
49
-
50
- response_entries.flatten.each { |res| process_response(res) }
51
- consolidate_answer
45
+ answer.process_response(response_entries)
46
+ return answer
52
47
  end
53
48
 
54
- private
55
-
56
- # Process the response depending on the requests lookup_type
57
- # if it is a :first lookup then we only want to set the result
58
- # once, if it's cascading, we should ammend the payload array
59
- #
60
- def process_response(res)
61
- case request.lookup_type
62
- when :first
63
- @answer.payload ||= res[:value]
64
- @answer.datatype ||= res[:datatype]
65
- when :cascade
66
- @answer.payload << res[:value]
67
- end
49
+ def register_datasource(datasource)
50
+ Jerakia::Datasource.load_datasource(datasource)
68
51
  end
69
52
 
70
- # Once all the responses are submitted into the answers payload
71
- # we need to consolidate the data based on the merge behaviour
72
- # requested.
73
- #
74
- def consolidate_answer
75
- if request.lookup_type == :cascade && @answer.payload.is_a?(Array)
76
- case request.merge
77
- when :array
78
- @answer.flatten_payload!
79
- when :hash, :deep_hash
80
- @answer.merge_payload!(request.merge)
81
- end
82
- end
53
+ def clone_request(request)
54
+ Marshal.load(Marshal.dump(request))
83
55
  end
56
+
84
57
  end
85
58
  end
@@ -1,7 +1,8 @@
1
1
  class Jerakia::Response
2
2
  module Filter
3
- def filter!(name, opts)
3
+ def filter!(name, opts = {})
4
4
  Jerakia::Util.autoload('response/filter', name)
5
+ Jerakia.log.debug("Invoking output filter #{name}")
5
6
  instance_eval "extend Jerakia::Response::Filter::#{name.to_s.capitalize}"
6
7
  instance_eval "self.filter_#{name} (#{opts})"
7
8
  end
@@ -1,51 +1,34 @@
1
- # Parts of this class are copied from https://github.com/TomPoulton/hiera-eyaml/blob/master/lib/hiera/backend/eyaml_backend.rb
2
- # The MIT License (MIT)
3
- #
4
- # Copyright (c) 2013 Tom Poulton
5
- #
6
- # Other code Copyright (c) 2014 Craig Dunn, Apache 2.0 License.
7
- #
8
-
9
- require 'hiera/backend/eyaml/encryptor'
10
- require 'hiera/backend/eyaml/utils'
11
- require 'hiera/backend/eyaml/options'
12
- require 'hiera/backend/eyaml/parser/parser'
13
- require 'hiera/filecache'
14
-
15
- require 'yaml'
1
+ require 'jerakia/encryption'
16
2
 
17
3
  class Jerakia::Response
18
4
  module Filter
19
5
  module Encryption
20
6
  def filter_encryption(_opts = {})
21
- parse_values do |val|
22
- decrypt val if val.is_a?(String)
23
- val
7
+ Jerakia.log.debug("Encryption filter started")
8
+ provider = Jerakia::Encryption.handler
9
+
10
+ unless provider.loaded?
11
+ raise Jerakia::Error, 'Cannot load encryption output filter, no encryption provider configured'
12
+ end
13
+ unless provider.respond_to?('signiture')
14
+ raise Jerakia::Error, 'Encryption provider did not provide a signiture method, cannot run output filter'
24
15
  end
25
- end
26
16
 
27
- def decrypt(data)
28
- if encrypted?(data)
29
- public_key = config['eyaml']['public_key']
30
- private_key = config['eyaml']['private_key']
31
- Hiera::Backend::Eyaml::Options[:pkcs7_private_key] = private_key
32
- Hiera::Backend::Eyaml::Options[:pkcs7_public_key] = public_key
33
- parser = Hiera::Backend::Eyaml::Parser::ParserFactory.hiera_backend_parser
17
+ signiture = provider.signiture
18
+ raise Jerakia::Error, "Encryption provider signiture is not a Regexp" unless signiture.is_a?(Regexp)
34
19
 
35
- tokens = parser.parse(data)
36
- decrypted = tokens.map(&:to_plain_text)
37
- plaintext = decrypted.join
38
- Jerakia.log.debug(plaintext)
39
- plaintext.chomp!
40
- data.clear.insert(0, plaintext)
41
- else
42
- data
20
+ # Match the signiture of the provider (from the signiture method) against the string
21
+ # if the string matches the regex then call the decrypt method of the encryption
22
+ # provider
23
+ #
24
+ parse_values do |val|
25
+ if val =~ signiture
26
+ decrypted = provider.decrypt(val)
27
+ val.clear.insert(0, decrypted)
28
+ end
29
+ val
43
30
  end
44
31
  end
45
-
46
- def encrypted?(data)
47
- /.*ENC\[.*?\]/ =~ data ? true : false
48
- end
49
32
  end
50
33
  end
51
34
  end
@@ -11,21 +11,21 @@ class Jerakia::Schema
11
11
  )
12
12
 
13
13
  Jerakia.log.debug("Schema lookup invoked for #{request.key} namespace: #{request.namespace}")
14
- schema_lookup = Jerakia::Launcher.new(schema_request)
15
14
 
16
15
  begin
17
- schema_lookup.evaluate do
16
+ schema_policy = Jerakia::Launcher.evaluate do
18
17
  policy :schema do
19
18
  lookup :schema do
20
19
  datasource *schema_datasource
21
20
  end
22
21
  end
23
22
  end
23
+ schema_lookup = schema_policy.run(schema_request)
24
24
  rescue Jerakia::Error => e
25
25
  raise Jerakia::SchemaError, "Schema lookup for #{request.key} failed: #{e.message}"
26
26
  end
27
27
 
28
- @schema_data = schema_lookup.answer.payload || {}
28
+ @schema_data = schema_lookup.payload || {}
29
29
 
30
30
  # Validate the returned data from the schema
31
31
  raise Jerakia::SchemaError, "Schema must return a hash for key #{request.key}" unless @schema_data.is_a?(Hash)
@@ -0,0 +1,51 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'openssl'
4
+
5
+ class Jerakia
6
+ module Util
7
+ class Http
8
+
9
+ class << self
10
+
11
+ def post(uri_str, data={}, headers={}, options={})
12
+ uri = URI.parse(uri_str)
13
+ request = Net::HTTP::Post.new(uri.path)
14
+ request.body = data.to_json
15
+ http_send(uri, request, headers, options)
16
+ end
17
+
18
+ def put(uri_str, data={}, headers={}, options={})
19
+ uri = URI.parse(uri_str)
20
+ request = Net::HTTP::Put.new(uri.path)
21
+ request.body = data.to_json
22
+ http_send(uri, request, headers, options)
23
+ end
24
+
25
+
26
+ def http_send(uri, request, headers={}, options={})
27
+ request.add_field('Content-Type', options[:content_type]) if options[:content_type]
28
+
29
+ headers.each do |header, value|
30
+ request.add_field(header, value)
31
+ end
32
+
33
+ http = Net::HTTP.new(uri.host, uri.port)
34
+ if options[:ssl]
35
+ http.use_ssl = true
36
+ http.verify_mode = options[:ssl_verify] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
37
+ http.cert = OpenSSL::X509::Certificate.new(options[:ssl_cert]) if options[:ssl_cert]
38
+ http.key = OpenSSL::PKey::RSA.new(options[:ssl_key]) if options[:ssl_key]
39
+ end
40
+
41
+ begin
42
+ response = http.request(request)
43
+ return response
44
+ rescue => e
45
+ raise Jerakia::HTTPError, e.message
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -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 = '1.2.1'.freeze
6
+ VERSION = '2.0.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: 1.2.1
4
+ version: 2.0.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-02-17 00:00:00.000000000 Z
11
+ date: 2017-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -116,7 +116,6 @@ extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
118
  - bin/jerakia
119
- - lib/hiera/backend/jerakia_backend.rb
120
119
  - lib/jerakia.rb
121
120
  - lib/jerakia/answer.rb
122
121
  - lib/jerakia/cache.rb
@@ -124,6 +123,7 @@ files:
124
123
  - lib/jerakia/cache/file.rb
125
124
  - lib/jerakia/cli.rb
126
125
  - lib/jerakia/cli/lookup.rb
126
+ - lib/jerakia/cli/secret.rb
127
127
  - lib/jerakia/cli/server.rb
128
128
  - lib/jerakia/cli/token.rb
129
129
  - lib/jerakia/config.rb
@@ -132,10 +132,11 @@ files:
132
132
  - lib/jerakia/datasource/file.rb
133
133
  - lib/jerakia/datasource/file/json.rb
134
134
  - lib/jerakia/datasource/file/yaml.rb
135
- - lib/jerakia/datasource/file_new.rb
136
135
  - lib/jerakia/datasource/http.rb
137
136
  - lib/jerakia/dsl/lookup.rb
138
137
  - lib/jerakia/dsl/policy.rb
138
+ - lib/jerakia/encryption.rb
139
+ - lib/jerakia/encryption/vault.rb
139
140
  - lib/jerakia/error.rb
140
141
  - lib/jerakia/launcher.rb
141
142
  - lib/jerakia/log.rb
@@ -145,7 +146,6 @@ files:
145
146
  - lib/jerakia/lookup/plugin_config.rb
146
147
  - lib/jerakia/lookup/pluginfactory.rb
147
148
  - lib/jerakia/policy.rb
148
- - lib/jerakia/policy/registry.rb
149
149
  - lib/jerakia/request.rb
150
150
  - lib/jerakia/response.rb
151
151
  - lib/jerakia/response/filter.rb
@@ -162,9 +162,8 @@ files:
162
162
  - lib/jerakia/server/auth/token.rb
163
163
  - lib/jerakia/server/rest.rb
164
164
  - lib/jerakia/util.rb
165
+ - lib/jerakia/util/http.rb
165
166
  - lib/jerakia/version.rb
166
- - lib/puppet/indirector/data_binding/jerakia.rb
167
- - lib/puppet/indirector/data_binding/jerakia_rest.rb
168
167
  homepage: http://jerakia.io
169
168
  licenses:
170
169
  - Apache 2.0
@@ -1,59 +0,0 @@
1
- require 'puppet'
2
- require 'puppet/resource'
3
-
4
- class Hiera
5
- module Backend
6
- class Jerakia_backend
7
- def initialize(config = nil)
8
- require 'jerakia'
9
- @config = config || Hiera::Config[:jerakia] || {}
10
- @policy = @config[:policy] || 'default'
11
- @jerakia = ::Jerakia.new(@config)
12
- Jerakia.log.debug("[hiera] hiera backend loaded with policy #{@policy}")
13
- end
14
-
15
- def lookup(key, scope, _order_override, resolution_type)
16
- lookup_type = :first
17
- merge_type = :none
18
-
19
- case resolution_type
20
- when :array
21
- lookup_type = :cascade
22
- merge_type = :array
23
- when :hash
24
- lookup_type = :cascade
25
- merge_type = :hash
26
- end
27
-
28
- namespace = []
29
-
30
- if key.include?('::')
31
- lookup_key = key.split('::')
32
- key = lookup_key.pop
33
- namespace = lookup_key
34
- end
35
-
36
- Jerakia.log.debug("[hiera] backend invoked for key #{key} using namespace #{namespace}")
37
-
38
- metadata = {}
39
- metadata = if scope.is_a?(Hash)
40
- scope.reject { |_k, v| v.is_a?(Puppet::Resource) }
41
- else
42
- scope.real.to_hash.reject { |_k, v| v.is_a?(Puppet::Resource) }
43
- end
44
-
45
- request = Jerakia::Request.new(
46
- :key => key,
47
- :namespace => namespace,
48
- :policy => metadata['jerakia_policy'] || @policy,
49
- :lookup_type => lookup_type,
50
- :merge => merge_type,
51
- :metadata => metadata
52
- )
53
-
54
- answer = @jerakia.lookup(request)
55
- answer.payload
56
- end
57
- end
58
- end
59
- end