hiera-file 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/hiera/backend/file_backend.rb +49 -13
- data/spec/unit/file_backend_spec.rb +53 -10
- metadata +2 -2
@@ -1,44 +1,80 @@
|
|
1
|
+
require 'hiera/config'
|
2
|
+
|
1
3
|
class Hiera
|
2
4
|
module Backend
|
3
5
|
class File_backend
|
4
6
|
def initialize
|
5
7
|
Hiera.debug("Hiera File backend starting")
|
8
|
+
|
9
|
+
if Hiera::Config.include?(:file) and Hiera::Config[:file].has_key? :interpolate
|
10
|
+
@interpolate = Hiera::Config[:file][:interpolate]
|
11
|
+
else
|
12
|
+
@interpolate = true
|
13
|
+
end
|
6
14
|
end
|
7
15
|
|
8
16
|
def lookup(key, scope, order_override, resolution_type)
|
9
17
|
answer = nil
|
10
18
|
|
11
|
-
Hiera.debug("Looking up #{key} in
|
19
|
+
Hiera.debug("Looking up #{key} in File backend")
|
12
20
|
|
13
21
|
Backend.datasources(scope, order_override) do |source|
|
14
22
|
Hiera.debug("Hiera File_backend: looking for data source '#{source}'")
|
15
23
|
|
16
24
|
datadir = Backend.datafile(:file, scope, source, "d") or next
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
abs_path = File.expand_path(File.join(abs_datadir, key))
|
23
|
-
unless abs_path.index(abs_datadir) == 0
|
24
|
-
raise Exception, "Hiera File backend: key lookup outside of datadir '#{key}'"
|
25
|
-
end
|
26
|
+
validate_key_lookup!(datadir, key)
|
27
|
+
|
28
|
+
path = File.join(datadir, key)
|
29
|
+
next unless File.exist?(path)
|
26
30
|
|
27
|
-
|
28
|
-
data = File.read(abs_path)
|
31
|
+
data = File.read(path)
|
29
32
|
|
30
33
|
case resolution_type
|
31
34
|
when :array
|
32
35
|
answer ||= []
|
33
|
-
answer <<
|
36
|
+
answer << parse_answer(data, scope)
|
34
37
|
else
|
35
|
-
answer =
|
38
|
+
answer = parse_answer(data, scope)
|
36
39
|
break
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
40
43
|
answer
|
41
44
|
end
|
45
|
+
|
46
|
+
# Ensure that looked up files are within the datadir to prevent directory traversal
|
47
|
+
#
|
48
|
+
# @param datadir [String] The directory being used for the lookup
|
49
|
+
# @param key [String] The key being looked up
|
50
|
+
#
|
51
|
+
# @todo Raise a SecurityError instead of an Exception
|
52
|
+
# @raise [Exception] If the path to the data file is outside of the datadir
|
53
|
+
def validate_key_lookup!(datadir, key)
|
54
|
+
|
55
|
+
# Expand the datadir and path, and ensure that the datadir contains
|
56
|
+
# the given key. If the expanded key is outside of the datadir then
|
57
|
+
# this is a directory traversal attack and should be aborted.
|
58
|
+
abs_datadir = File.expand_path(datadir)
|
59
|
+
abs_path = File.expand_path(File.join(abs_datadir, key))
|
60
|
+
unless abs_path.index(abs_datadir) == 0
|
61
|
+
raise Exception, "Hiera File backend: key lookup outside of datadir '#{key}'"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Parse the answer according to the chosen interpolation mode
|
66
|
+
#
|
67
|
+
# @param data [String] The value to parse
|
68
|
+
# @param scope [Hash] The variable scope to use for interpolation
|
69
|
+
#
|
70
|
+
# @return [String] The interpolated data
|
71
|
+
def parse_answer(data, scope)
|
72
|
+
if @interpolate
|
73
|
+
Backend.parse_answer(data, scope)
|
74
|
+
else
|
75
|
+
data
|
76
|
+
end
|
77
|
+
end
|
42
78
|
end
|
43
79
|
end
|
44
80
|
end
|
@@ -7,8 +7,9 @@ class Hiera
|
|
7
7
|
before do
|
8
8
|
Hiera.stubs(:debug)
|
9
9
|
Hiera.stubs(:warn)
|
10
|
-
end
|
11
10
|
|
11
|
+
Hiera::Config.load(:backends => :file)
|
12
|
+
end
|
12
13
|
|
13
14
|
describe "#initialize" do
|
14
15
|
it "should announce its creation" do # because other specs checks this
|
@@ -23,8 +24,6 @@ class Hiera
|
|
23
24
|
Backend.stubs(:datasources).multiple_yields(["one"], ["two"])
|
24
25
|
end
|
25
26
|
|
26
|
-
subject { File_backend.new }
|
27
|
-
|
28
27
|
it "should look for data in all sources" do
|
29
28
|
Backend.expects(:datafile).with(:file, {}, "one", "d")
|
30
29
|
Backend.expects(:datafile).with(:file, {}, "two", "d")
|
@@ -59,16 +58,60 @@ class Hiera
|
|
59
58
|
subject.lookup("key", {}, nil, :array).should == ['value one', 'value two']
|
60
59
|
end
|
61
60
|
|
62
|
-
|
63
|
-
|
61
|
+
describe "With interpolation" do
|
62
|
+
after do
|
63
|
+
Hiera::Config.load({:file => {}})
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
describe "explicitly enabled" do
|
67
|
+
before do
|
68
|
+
Hiera::Config.load({:file => {:interpolate => true}})
|
69
|
+
end
|
67
70
|
|
68
|
-
|
69
|
-
|
71
|
+
it "should parse the answer for scope variables" do
|
72
|
+
scope = {'scope_val' => 'v'}
|
73
|
+
|
74
|
+
Backend.expects(:datafile).with(:file, scope, "one", "d").returns("/datadir/one.d")
|
75
|
+
Backend.expects(:datafile).with(:file, scope, "two", "d").never
|
76
|
+
|
77
|
+
File.expects(:exist?).with("/datadir/one.d/key").returns true
|
78
|
+
File.expects(:read).with("/datadir/one.d/key").returns '%{scope_val}alue'
|
79
|
+
|
80
|
+
subject.lookup("key", scope, nil, :priority).should == 'value'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "set to default" do
|
85
|
+
it "should parse the answer for scope variables" do
|
86
|
+
scope = {'scope_val' => 'v'}
|
87
|
+
|
88
|
+
Backend.expects(:datafile).with(:file, scope, "one", "d").returns("/datadir/one.d")
|
89
|
+
Backend.expects(:datafile).with(:file, scope, "two", "d").never
|
90
|
+
|
91
|
+
File.expects(:exist?).with("/datadir/one.d/key").returns true
|
92
|
+
File.expects(:read).with("/datadir/one.d/key").returns '%{scope_val}alue'
|
93
|
+
|
94
|
+
subject.lookup("key", scope, nil, :priority).should == 'value'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "explicitly disabled" do
|
99
|
+
before do
|
100
|
+
Hiera::Config.load({:file => {:interpolate => false}})
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should not parse the answer for scope variables" do
|
104
|
+
scope = {'scope_val' => 'v'}
|
105
|
+
|
106
|
+
Backend.expects(:datafile).with(:file, scope, "one", "d").returns("/datadir/one.d")
|
107
|
+
Backend.expects(:datafile).with(:file, scope, "two", "d").never
|
108
|
+
|
109
|
+
File.expects(:exist?).with("/datadir/one.d/key").returns true
|
110
|
+
File.expects(:read).with("/datadir/one.d/key").returns '%{scope_val}alue'
|
70
111
|
|
71
|
-
|
112
|
+
subject.lookup("key", scope, nil, :priority).should == '%{scope_val}alue'
|
113
|
+
end
|
114
|
+
end
|
72
115
|
end
|
73
116
|
|
74
117
|
it "should prevent directory traversal attacks" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hiera-file
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hiera
|