jerakia 0.0.8
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 +7 -0
- data/bin/jerakia +71 -0
- data/lib/hiera/backend/jerakia_backend.rb +67 -0
- data/lib/jerakia/answer.rb +36 -0
- data/lib/jerakia/cache.rb +24 -0
- data/lib/jerakia/config.rb +25 -0
- data/lib/jerakia/datamodel.rb +9 -0
- data/lib/jerakia/datasource/dummy.rb +17 -0
- data/lib/jerakia/datasource/file/yaml.rb +17 -0
- data/lib/jerakia/datasource/file.rb +65 -0
- data/lib/jerakia/datasource.rb +39 -0
- data/lib/jerakia/launcher.rb +34 -0
- data/lib/jerakia/log.rb +52 -0
- data/lib/jerakia/lookup.rb +92 -0
- data/lib/jerakia/plugins/lookup/confine.rb +20 -0
- data/lib/jerakia/plugins/lookup/hiera_compat.rb +26 -0
- data/lib/jerakia/policy.rb +65 -0
- data/lib/jerakia/request.rb +21 -0
- data/lib/jerakia/response/filter/encryption.rb +56 -0
- data/lib/jerakia/response/filter/strsub.rb +35 -0
- data/lib/jerakia/response/filter.rb +9 -0
- data/lib/jerakia/response.rb +57 -0
- data/lib/jerakia/scope/metadata.rb +18 -0
- data/lib/jerakia/scope.rb +14 -0
- data/lib/jerakia/test.pp +302 -0
- data/lib/jerakia/util.rb +52 -0
- data/lib/jerakia.rb +72 -0
- data/lib/puppet/indirector/data_binding/jerakia.rb +37 -0
- data/lib/puppet/indirector/data_binding/jerakia_rest.rb +46 -0
- data/lib/test.pp +302 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e7a0ffdcc717ef8705465da1d89d701353e31a4d
|
4
|
+
data.tar.gz: a40d224bb84863097b2b1e4d877aa5b8bfbed9c7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a1e2f422baea90e6bc37df8bd5ed1b9717b41a3968b4eb44ad50dfa80eb1defdc11461da6f57e749fd074d4a986a9f135ea9ddee6797fcd9a73ef14dcca0e9b5
|
7
|
+
data.tar.gz: a6f211698de9b7286b674e76285f9720bc7c50a70f5bb9d9d121610592fae36ecf5d0bb858fdaf54ea7268d3108f93f322514a5f4cefbe8d963b02ac9c61d931
|
data/bin/jerakia
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'jerakia'
|
4
|
+
require 'json'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
options = {
|
8
|
+
:policy => "default",
|
9
|
+
:config => "/etc/jerakia/jerakia.yml",
|
10
|
+
:scope => nil,
|
11
|
+
:key => nil,
|
12
|
+
:merge => "array",
|
13
|
+
:lookup_type => "first",
|
14
|
+
:namespace => nil,
|
15
|
+
:metadata => {},
|
16
|
+
}
|
17
|
+
|
18
|
+
OptionParser.new do |opts|
|
19
|
+
|
20
|
+
opts.on("--config CONFIG","-c","Config file") do |c|
|
21
|
+
options[:config] = c
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("--key KEY", "-k", "Lookup key") do |k|
|
25
|
+
options[:key] = k
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("--policy POLICY", "-p", "Policy") do |p|
|
29
|
+
options[:policy] = p.to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("--namespace NAMESPACE", "-n", "Namespace") do |n|
|
33
|
+
options[:namespace] = n.split(/::/)
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("--type TYPE", "-t", "Lookup type") do |t|
|
37
|
+
options[:lookup_type] = t.to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("--scope SCOPE", "-s", "Scope handler") do |s|
|
41
|
+
options[:scope] = s.to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("--merge MERGE", "-m", "Merge type") do |m|
|
45
|
+
options[:merge] = m.to_sym
|
46
|
+
end
|
47
|
+
end.parse!
|
48
|
+
|
49
|
+
unless ARGV.empty?
|
50
|
+
ARGV.each do |arg|
|
51
|
+
meta=arg.split(':')
|
52
|
+
options[:metadata][meta[0]] = meta[1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
jac = Jerakia.new({:config => options[:config]})
|
59
|
+
req = Jerakia::Request.new(
|
60
|
+
:key => options[:key],
|
61
|
+
:namespace => options[:namespace],
|
62
|
+
:policy => options[:policy].to_sym,
|
63
|
+
:lookup_type => options[:lookup_type].to_sym,
|
64
|
+
:merge => options[:merge].to_sym,
|
65
|
+
:loglevel => 'debug',
|
66
|
+
:metadata => options[:metadata]
|
67
|
+
)
|
68
|
+
|
69
|
+
|
70
|
+
answer = jac.lookup(req)
|
71
|
+
puts answer.payload.to_json
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Hiera
|
2
|
+
module Backend
|
3
|
+
class Jerakia_backend
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
require 'jerakia'
|
7
|
+
@config = Config[:jerakia] || {}
|
8
|
+
@policy = @config[:policy] || 'default'
|
9
|
+
@jerakia = ::Jerakia.new(Config[:jerakia] || {})
|
10
|
+
Jerakia.log.debug("[hiera] hiera backend loaded with policy #{@policy}")
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def lookup(key, scope, order_override, resolution_type)
|
16
|
+
|
17
|
+
|
18
|
+
lookup_type = :first
|
19
|
+
merge_type = :none
|
20
|
+
|
21
|
+
case resolution_type
|
22
|
+
when :array
|
23
|
+
lookup_type = :cascade
|
24
|
+
merge_type = :array
|
25
|
+
when :hash
|
26
|
+
lookup_type = :cascade
|
27
|
+
merge_type = :hash
|
28
|
+
end
|
29
|
+
|
30
|
+
namespace = []
|
31
|
+
|
32
|
+
if key.include?('::')
|
33
|
+
lookup_key = key.split('::')
|
34
|
+
namespace << lookup_key.shift
|
35
|
+
key = lookup_key.join('::')
|
36
|
+
end
|
37
|
+
|
38
|
+
Jerakia.log.debug("[hiera] backend invoked for key #{key} using namespace #{namespace}")
|
39
|
+
|
40
|
+
metadata={}
|
41
|
+
if scope.is_a?(Hash)
|
42
|
+
metadata=scope
|
43
|
+
else
|
44
|
+
metadata = scope.real.to_hash
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
request = Jerakia::Request.new(
|
49
|
+
:key => key,
|
50
|
+
:namespace => namespace,
|
51
|
+
:policy => @policy,
|
52
|
+
:lookup_type => lookup_type,
|
53
|
+
:merge => merge_type,
|
54
|
+
:metadata => metadata,
|
55
|
+
)
|
56
|
+
|
57
|
+
answer = @jerakia.lookup(request)
|
58
|
+
answer.payload
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Jerakia::Answer
|
2
|
+
|
3
|
+
attr_accessor :payload
|
4
|
+
attr_accessor :datatype
|
5
|
+
attr_reader :lookup_type
|
6
|
+
|
7
|
+
def initialize(lookup_type = :first)
|
8
|
+
case lookup_type
|
9
|
+
when :first
|
10
|
+
@payload=nil
|
11
|
+
when :cascade
|
12
|
+
@payload=[]
|
13
|
+
@datatype="array"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def flatten_payload!
|
18
|
+
@payload.flatten!
|
19
|
+
end
|
20
|
+
|
21
|
+
def merge_payload!
|
22
|
+
payload_hash={}
|
23
|
+
@payload.each do |p|
|
24
|
+
if p.is_a?(Hash)
|
25
|
+
payload_hash.merge!(p)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@payload=payload_hash
|
29
|
+
set_data_type
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_data_type
|
33
|
+
@data_type=@payload.class.to_s.downcase
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Very primitive form of cache - but we'll make this smarter
|
3
|
+
#
|
4
|
+
#
|
5
|
+
class Jerakia::Cache
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@@bucket = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def bucket_add(index,data)
|
12
|
+
@@bucket[index] = data
|
13
|
+
data
|
14
|
+
end
|
15
|
+
|
16
|
+
def in_bucket?(index)
|
17
|
+
@@bucket.has_key?(index)
|
18
|
+
end
|
19
|
+
|
20
|
+
def bucket
|
21
|
+
@@bucket
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Jerakia::Config
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
attr_reader :policydir
|
5
|
+
attr_reader :server_url
|
6
|
+
|
7
|
+
def initialize(config='/etc/jerakia/jerakia.yml')
|
8
|
+
unless File.exists?(config)
|
9
|
+
Jerakia.crit("Config file #{config} not found")
|
10
|
+
end
|
11
|
+
rawdata=File.read(config)
|
12
|
+
ymldata=YAML.load(rawdata)
|
13
|
+
@policydir=ymldata['policydir']
|
14
|
+
@server_url=ymldata['server_url']
|
15
|
+
@configdata=ymldata
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
@configdata[key.to_s]
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Jerakia::Datasource
|
2
|
+
module Dummy
|
3
|
+
|
4
|
+
def run
|
5
|
+
#
|
6
|
+
# Do the lookup
|
7
|
+
|
8
|
+
Jerakia.log.debug("Searching key #{lookup.request.key} in dummy datasource")
|
9
|
+
option :return, { :type => String, :default => "Returned data" }
|
10
|
+
response.submit options[:return]
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Jerakia::Datasource
|
2
|
+
module File
|
3
|
+
class Yaml
|
4
|
+
class << self
|
5
|
+
require 'yaml'
|
6
|
+
def import_file(fname, extension='yml')
|
7
|
+
diskfile="#{fname}.#{extension}"
|
8
|
+
Jerakia.log.debug("scanning file #{diskfile}")
|
9
|
+
return {} unless ::File.exists?(diskfile)
|
10
|
+
data=::File.read(diskfile)
|
11
|
+
YAML.load(data)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class Jerakia::Datasource
|
2
|
+
module File
|
3
|
+
|
4
|
+
attr_reader :file_format
|
5
|
+
def load_format_handler
|
6
|
+
format = options[:format] || :yaml
|
7
|
+
class_name=format.to_s.capitalize
|
8
|
+
require "jerakia/datasource/file/#{format.to_s}"
|
9
|
+
@file_format = eval "Jerakia::Datasource::File::#{class_name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def read_from_file(fname)
|
13
|
+
fpath = []
|
14
|
+
fpath << options[:docroot] unless fname[0] == '/'
|
15
|
+
fpath << [ fname, lookup.request.namespace ]
|
16
|
+
diskname = ::File.join(fpath.flatten).gsub(/\/$/, '')
|
17
|
+
|
18
|
+
Jerakia.log.debug("read_from_file() #{fname} using diskname #{diskname}")
|
19
|
+
|
20
|
+
import_args=[]
|
21
|
+
import_args << diskname
|
22
|
+
import_args << options[:extension] if options[:extension]
|
23
|
+
|
24
|
+
cache_index={ :diskname => diskname, :format => options[:format] }
|
25
|
+
if options[:enable_caching]
|
26
|
+
if in_bucket?(cache_index)
|
27
|
+
Jerakia.log.debug("returning cached data #{bucket[cache_index]}")
|
28
|
+
bucket[cache_index]
|
29
|
+
else
|
30
|
+
Jerakia.log.debug("adding to cache #{@file_format.import_file(*import_args)}")
|
31
|
+
bucket_add(cache_index,@file_format.import_file(*import_args))
|
32
|
+
end
|
33
|
+
else
|
34
|
+
@file_format.import_file(*import_args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def run
|
40
|
+
#
|
41
|
+
# Do the lookup
|
42
|
+
|
43
|
+
Jerakia.log.debug("Searching key #{lookup.request.key} from file format #{options[:format]} (#{whoami})")
|
44
|
+
option :searchpath, { :type => Array, :mandatory => true }
|
45
|
+
option :format, { :type => Symbol, :default => :yaml }
|
46
|
+
option :docroot, { :type => String, :default => "/etc/jerakia/data" }
|
47
|
+
option :extension, { :type => String }
|
48
|
+
|
49
|
+
load_format_handler
|
50
|
+
|
51
|
+
options[:searchpath].each do |path|
|
52
|
+
Jerakia.log.debug("Attempting to load data from #{path}")
|
53
|
+
return unless response.want?
|
54
|
+
data=read_from_file(path)
|
55
|
+
Jerakia.log.debug("Datasource provided #{data} looking for key #{lookup.request.key}")
|
56
|
+
if data[lookup.request.key]
|
57
|
+
Jerakia.log.debug("Found data #{data[lookup.request.key]}")
|
58
|
+
response.submit data[lookup.request.key]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'jerakia/cache'
|
2
|
+
class Jerakia::Datasource < Jerakia::Cache
|
3
|
+
|
4
|
+
require 'jerakia/response'
|
5
|
+
attr_reader :response
|
6
|
+
attr_reader :options
|
7
|
+
attr_reader :lookup
|
8
|
+
|
9
|
+
def initialize(name, lookup, opts)
|
10
|
+
@response = Jerakia::Response.new(lookup)
|
11
|
+
@options = opts
|
12
|
+
@lookup = lookup
|
13
|
+
@name = name
|
14
|
+
require "jerakia/datasource/#{name.to_s}"
|
15
|
+
# rescue loaderrer
|
16
|
+
eval "extend Jerakia::Datasource::#{name.to_s.capitalize}"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
## used for verbose logging
|
21
|
+
def whoami
|
22
|
+
"datasource=#{@name} lookup=#{@lookup.name}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def option(opt, data={})
|
26
|
+
@options[opt] ||= data[:default] || nil
|
27
|
+
Jerakia.log.debug("[#{whoami}]: options[#{opt}] to #{options[opt]} [#{options[opt].class}]")
|
28
|
+
if @options[opt].nil?
|
29
|
+
Jerakia.crit "#{opt} must be configured in #{whoami}" if data[:mandatory]
|
30
|
+
else
|
31
|
+
if data[:type]
|
32
|
+
Jerakia.crit "#{opt} must be a #{data[:type].to_s} in #{whoami}" unless @options[opt].is_a?(data[:type])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Here we take a request object and read in the policy file
|
2
|
+
# which is evalulated in this instance
|
3
|
+
#
|
4
|
+
class Jerakia::Launcher
|
5
|
+
|
6
|
+
attr_reader :request
|
7
|
+
attr_reader :answer
|
8
|
+
def initialize(req)
|
9
|
+
@@request = req
|
10
|
+
invoke
|
11
|
+
end
|
12
|
+
|
13
|
+
def invoke
|
14
|
+
policy_name=request.policy.to_s
|
15
|
+
Jerakia.log.info "Invoked lookup for #{@@request.key} using policy #{policy_name}"
|
16
|
+
filename=File.join(Jerakia.config.policydir, "#{policy_name}.rb")
|
17
|
+
policydata=Jerakia.filecache(filename)
|
18
|
+
instance_eval policydata
|
19
|
+
end
|
20
|
+
|
21
|
+
def request
|
22
|
+
@@request
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def policy(name, opts={}, &block)
|
27
|
+
policy = Jerakia::Policy.new(name, opts, &block)
|
28
|
+
policy.fire!
|
29
|
+
@answer = policy.answer
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
data/lib/jerakia/log.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class Jerakia::Log < Jerakia
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
def initialize(level=:info)
|
5
|
+
@@logfile ||= config[:logfile] || '/var/log/jerakia.log'
|
6
|
+
@@logger ||= Logger.new(@@logfile)
|
7
|
+
@@level ||= level
|
8
|
+
case @@level
|
9
|
+
when :info
|
10
|
+
@@logger.level = Logger::INFO
|
11
|
+
when :debug
|
12
|
+
@@logger.level = Logger::DEBUG
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def info(msg)
|
17
|
+
@@logger.info msg
|
18
|
+
end
|
19
|
+
|
20
|
+
def debug(msg)
|
21
|
+
@@logger.debug msg
|
22
|
+
end
|
23
|
+
|
24
|
+
def error(msg)
|
25
|
+
@@logger.error msg
|
26
|
+
end
|
27
|
+
|
28
|
+
def fatal(msg)
|
29
|
+
@@logger.fatal msg
|
30
|
+
end
|
31
|
+
|
32
|
+
# def self.fatal(msg)
|
33
|
+
# self.new.fatal msg
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# def self.error(msg)
|
37
|
+
# self.new.error msg
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
def self.debug(msg)
|
41
|
+
self.new.debug msg
|
42
|
+
end
|
43
|
+
#
|
44
|
+
## def self.info(msg)
|
45
|
+
# puts @@logger
|
46
|
+
# self.new.info msg
|
47
|
+
# end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class Jerakia::Lookup
|
2
|
+
require 'jerakia/datasource'
|
3
|
+
require 'jerakia/scope'
|
4
|
+
require 'jerakia/plugins/lookup/hiera_compat'
|
5
|
+
require 'jerakia/plugins/lookup/confine'
|
6
|
+
|
7
|
+
attr_accessor :request
|
8
|
+
attr_reader :datasource
|
9
|
+
attr_reader :valid
|
10
|
+
attr_reader :lookuptype
|
11
|
+
attr_reader :scope_object
|
12
|
+
attr_reader :output_filters
|
13
|
+
attr_reader :name
|
14
|
+
attr_reader :proceed
|
15
|
+
|
16
|
+
def initialize(name,req,scope,&block)
|
17
|
+
|
18
|
+
@name=name
|
19
|
+
@request=req
|
20
|
+
@valid=true
|
21
|
+
@scope_object=scope
|
22
|
+
@output_filters=[]
|
23
|
+
@proceed=true
|
24
|
+
extend Jerakia::Lookup::Plugin
|
25
|
+
instance_eval &block
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def datasource(source, opts={})
|
30
|
+
@datasource = Jerakia::Datasource.new(source, self, opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
# If set, Jerakia will pass each Jerakia::Response object
|
34
|
+
# to an output filter plugin
|
35
|
+
#
|
36
|
+
|
37
|
+
def scope
|
38
|
+
@scope_object.value
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def output_filter(name,opts={})
|
43
|
+
@output_filters << { :name => name, :opts => opts }
|
44
|
+
end
|
45
|
+
|
46
|
+
def proceed?
|
47
|
+
@proceed
|
48
|
+
end
|
49
|
+
|
50
|
+
## lookup function: stop
|
51
|
+
# Enabling stop sets @proceed to false, which will cause Jerakia
|
52
|
+
# *not* to load any more lookups in the policy if this lookup is
|
53
|
+
# deemed as valid. If the lookup is invalidated than Jerakia *will*
|
54
|
+
# progress to the next lookup. This is useful in conjuction with
|
55
|
+
# the confine plugin where we want to segregate some lookups but
|
56
|
+
# not worry about excluding from later lookups
|
57
|
+
#
|
58
|
+
def stop
|
59
|
+
@proceed = false
|
60
|
+
end
|
61
|
+
|
62
|
+
## lookup function: continue
|
63
|
+
# Will cause Jerakia to continue to the next lookup in the policy
|
64
|
+
# which is the default behaviour
|
65
|
+
#
|
66
|
+
def continue
|
67
|
+
@proceed = true
|
68
|
+
end
|
69
|
+
|
70
|
+
## lookup function: invalidate
|
71
|
+
# Setting invalidate will mean this lookup will be skipped in the policy
|
72
|
+
#
|
73
|
+
def invalidate
|
74
|
+
@valid=false
|
75
|
+
end
|
76
|
+
|
77
|
+
def valid?
|
78
|
+
return @valid
|
79
|
+
end
|
80
|
+
|
81
|
+
def run
|
82
|
+
@datasource.run
|
83
|
+
response=@datasource.response
|
84
|
+
@output_filters.each do |filter|
|
85
|
+
response.filter! filter[:name], filter[:opts]
|
86
|
+
end
|
87
|
+
return response
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
end
|
92
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Jerakia::Lookup
|
2
|
+
module Plugin
|
3
|
+
|
4
|
+
def confine(key=nil,match)
|
5
|
+
if key
|
6
|
+
invalidate unless key[Regexp.new(match)] == key
|
7
|
+
else
|
8
|
+
invalidate
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def exclude(key=nil,match)
|
13
|
+
if key
|
14
|
+
invalidate if key[Regexp.new(match)] == key
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# This plugin reformats the lookup key according to a puppet's
|
2
|
+
# Hiera system, so instead of looking up <key> in <path>/<namespace>.yml
|
3
|
+
# we lookup <namespace>::<key> in <path>.yml
|
4
|
+
#
|
5
|
+
# This is a useful plugin for people wanting to test drive Jerakia
|
6
|
+
# but maintain an existing hiera filesystem layout and naming convention
|
7
|
+
# within the source data.
|
8
|
+
#
|
9
|
+
class Jerakia::Lookup
|
10
|
+
module Plugin
|
11
|
+
def hiera_compat
|
12
|
+
request.key.prepend("#{request.namespace.join('::')}::")
|
13
|
+
request.namespace=[]
|
14
|
+
end
|
15
|
+
|
16
|
+
def calling_module
|
17
|
+
if request.namespace.length > 0
|
18
|
+
request.namespace[0]
|
19
|
+
else
|
20
|
+
Jerakia.log.error("hiera_compat plugin tried to use calling_module but there is no namespace declared. Ensure that calling_module is called before hiera_compat in the policy")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'jerakia/launcher'
|
2
|
+
|
3
|
+
class Jerakia::Policy < Jerakia::Launcher
|
4
|
+
require 'jerakia/answer'
|
5
|
+
|
6
|
+
attr_accessor :lookups
|
7
|
+
attr_reader :routes
|
8
|
+
attr_reader :answer
|
9
|
+
attr_reader :scope
|
10
|
+
attr_reader :lookup_proceed
|
11
|
+
|
12
|
+
def initialize(name, opts, &block)
|
13
|
+
@lookups=[]
|
14
|
+
@routes={}
|
15
|
+
@answer=Jerakia::Answer.new(request.lookup_type)
|
16
|
+
@scope=Jerakia::Scope.new
|
17
|
+
@lookup_proceed = true
|
18
|
+
begin
|
19
|
+
instance_eval &block
|
20
|
+
rescue => e
|
21
|
+
Jerakia.fatal "Error processing policy file", e
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def clone_request
|
26
|
+
Marshal.load(Marshal.dump(request))
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def lookup(name,opts={},&block)
|
31
|
+
# We specifically clone the request object to allow plugins to modify the
|
32
|
+
# request payload for the scope of this lookup only.
|
33
|
+
#
|
34
|
+
lookup = Jerakia::Lookup.new(name,clone_request,scope,&block)
|
35
|
+
Jerakia.log.debug("Proceed to next lookup #{lookup.proceed?}")
|
36
|
+
|
37
|
+
@lookups << lookup if lookup.valid? and @lookup_proceed
|
38
|
+
@lookup_proceed = false if !lookup.proceed? and lookup.valid?
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def fire!
|
43
|
+
@lookups.each do |l|
|
44
|
+
responses = l.run
|
45
|
+
responses.entries.each do |res|
|
46
|
+
case request.lookup_type
|
47
|
+
when :first
|
48
|
+
@answer.payload ||= res[:value]
|
49
|
+
@answer.datatype ||= res[:datatype]
|
50
|
+
when :cascade
|
51
|
+
@answer.payload << res[:value]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if request.lookup_type == :cascade && @answer.payload.is_a?(Array) && request.merge == :array
|
56
|
+
@answer.flatten_payload!
|
57
|
+
end
|
58
|
+
if request.lookup_type == :cascade && @answer.payload.is_a?(Array) && request.merge == :hash
|
59
|
+
@answer.merge_payload!
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Jerakia::Request
|
2
|
+
|
3
|
+
attr_accessor :key
|
4
|
+
attr_accessor :namespace
|
5
|
+
attr_accessor :merge
|
6
|
+
attr_accessor :policy
|
7
|
+
attr_accessor :metadata
|
8
|
+
attr_accessor :lookup_type
|
9
|
+
attr_accessor :scope
|
10
|
+
|
11
|
+
def initialize(opts={})
|
12
|
+
@key = opts[:key] || ''
|
13
|
+
@namespace = opts[:namespace] || []
|
14
|
+
@merge = opts[:merge] || false
|
15
|
+
@policy = opts[:policy] || 'default'
|
16
|
+
@metadata = opts[:metadata] || {}
|
17
|
+
@lookup_type = opts[:lookup_type] || :first
|
18
|
+
@scope = opts[:scope] || nil
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|