puppet 3.1.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/conf/auth.conf +3 -3
- data/lib/puppet/indirector/catalog/compiler.rb +13 -2
- data/lib/puppet/indirector/certificate_status/file.rb +5 -0
- data/lib/puppet/indirector/errors.rb +5 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +4 -0
- data/lib/puppet/indirector/file_bucket_file/selector.rb +4 -0
- data/lib/puppet/indirector/indirection.rb +2 -1
- data/lib/puppet/indirector/resource/active_record.rb +2 -0
- data/lib/puppet/indirector/resource/ral.rb +3 -0
- data/lib/puppet/indirector/resource/store_configs.rb +3 -0
- data/lib/puppet/indirector/resource/validator.rb +8 -0
- data/lib/puppet/indirector/rest.rb +4 -0
- data/lib/puppet/indirector/run/local.rb +4 -0
- data/lib/puppet/indirector/terminus.rb +20 -0
- data/lib/puppet/network/authconfig.rb +1 -1
- data/lib/puppet/network/formats.rb +3 -3
- data/lib/puppet/network/http/handler.rb +7 -2
- data/lib/puppet/network/http/rack/rest.rb +7 -2
- data/lib/puppet/network/http/webrick.rb +1 -0
- data/lib/puppet/parser/templatewrapper.rb +16 -16
- data/lib/puppet/util/monkey_patches.rb +38 -0
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/file_serving/terminus_helper_spec.rb +1 -1
- data/spec/integration/indirector/catalog/queue_spec.rb +1 -1
- data/spec/integration/resource/catalog_spec.rb +1 -0
- data/spec/unit/indirector/catalog/compiler_spec.rb +29 -2
- data/spec/unit/indirector/indirection_spec.rb +17 -1
- data/spec/unit/indirector/terminus_spec.rb +45 -0
- data/spec/unit/network/authconfig_spec.rb +12 -0
- data/spec/unit/network/authorization_spec.rb +4 -0
- data/spec/unit/network/formats_spec.rb +6 -6
- data/spec/unit/network/http/connection_spec.rb +0 -1
- data/spec/unit/network/http/handler_spec.rb +25 -0
- data/spec/unit/network/http/rack/rest_spec.rb +17 -0
- data/spec/unit/network/http/webrick_spec.rb +4 -0
- data/spec/unit/parser/functions/inline_template_spec.rb +15 -44
- data/spec/unit/parser/functions/template_spec.rb +43 -56
- data/spec/unit/parser/templatewrapper_spec.rb +68 -91
- data/spec/unit/ssl/certificate_request_spec.rb +2 -0
- data/spec/unit/ssl/host_spec.rb +1 -0
- data/spec/unit/util/monkey_patches_spec.rb +20 -0
- metadata +2190 -2188
@@ -13,7 +13,7 @@ end
|
|
13
13
|
describe Puppet::FileServing::TerminusHelper do
|
14
14
|
it "should be able to recurse on a single file" do
|
15
15
|
@path = Tempfile.new("fileset_integration")
|
16
|
-
request = Puppet::Indirector::Request.new(:metadata, :find, @path.path, :recurse => true)
|
16
|
+
request = Puppet::Indirector::Request.new(:metadata, :find, @path.path, nil, :recurse => true)
|
17
17
|
|
18
18
|
tester = TerminusHelperIntegrationTester.new
|
19
19
|
lambda { tester.path2instances(request, @path.path) }.should_not raise_error
|
@@ -6,7 +6,7 @@ require 'puppet/resource/catalog'
|
|
6
6
|
describe "Puppet::Resource::Catalog::Queue" do
|
7
7
|
before do
|
8
8
|
Puppet::Resource::Catalog.indirection.terminus(:queue)
|
9
|
-
@catalog = Puppet::Resource::Catalog.new
|
9
|
+
@catalog = Puppet::Resource::Catalog.new("foo")
|
10
10
|
|
11
11
|
@one = Puppet::Resource.new(:file, "/one")
|
12
12
|
@two = Puppet::Resource.new(:file, "/two")
|
@@ -46,6 +46,7 @@ describe Puppet::Resource::Catalog do
|
|
46
46
|
Puppet::Resource::Catalog.indirection.stubs(:terminus).returns terminus
|
47
47
|
|
48
48
|
node = mock 'node'
|
49
|
+
terminus.stubs(:validate)
|
49
50
|
terminus.expects(:find).with { |request| request.options[:use_node] == node }
|
50
51
|
Puppet::Resource::Catalog.indirection.find("me", :use_node => node)
|
51
52
|
end
|
@@ -53,13 +53,22 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
53
53
|
@request = Puppet::Indirector::Request.new(:catalog, :find, @name, nil, :node => @name)
|
54
54
|
end
|
55
55
|
|
56
|
-
it "should directly use provided nodes" do
|
56
|
+
it "should directly use provided nodes for a local request" do
|
57
57
|
Puppet::Node.indirection.expects(:find).never
|
58
58
|
@compiler.expects(:compile).with(@node)
|
59
59
|
@request.stubs(:options).returns(:use_node => @node)
|
60
|
+
@request.stubs(:remote?).returns(false)
|
60
61
|
@compiler.find(@request)
|
61
62
|
end
|
62
63
|
|
64
|
+
it "rejects a provided node if the request is remote" do
|
65
|
+
@request.stubs(:options).returns(:use_node => @node)
|
66
|
+
@request.stubs(:remote?).returns(true)
|
67
|
+
expect {
|
68
|
+
@compiler.find(@request)
|
69
|
+
}.to raise_error Puppet::Error, /invalid option use_node/i
|
70
|
+
end
|
71
|
+
|
63
72
|
it "should use the authenticated node name if no request key is provided" do
|
64
73
|
@request.stubs(:key).returns(nil)
|
65
74
|
Puppet::Node.indirection.expects(:find).with(@name, anything).returns(@node)
|
@@ -99,6 +108,24 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
99
108
|
@compiler.find(@request)
|
100
109
|
end
|
101
110
|
|
111
|
+
it "requires `facts_format` option if facts are passed in" do
|
112
|
+
facts = Puppet::Node::Facts.new("mynode", :afact => "avalue")
|
113
|
+
request = Puppet::Indirector::Request.new(:catalog, :find, "mynode", nil, :facts => facts)
|
114
|
+
expect {
|
115
|
+
@compiler.find(request)
|
116
|
+
}.to raise_error ArgumentError, /no fact format provided for mynode/
|
117
|
+
end
|
118
|
+
|
119
|
+
it "rejects facts in the request from a different node" do
|
120
|
+
facts = Puppet::Node::Facts.new("differentnode", :afact => "avalue")
|
121
|
+
request = Puppet::Indirector::Request.new(
|
122
|
+
:catalog, :find, "mynode", nil, :facts => facts, :facts_format => "unused"
|
123
|
+
)
|
124
|
+
expect {
|
125
|
+
@compiler.find(request)
|
126
|
+
}.to raise_error Puppet::Error, /fact definition for the wrong node/i
|
127
|
+
end
|
128
|
+
|
102
129
|
it "should return the results of compiling as the catalog" do
|
103
130
|
Puppet::Node.indirection.stubs(:find).returns(@node)
|
104
131
|
config = mock 'config'
|
@@ -133,7 +160,7 @@ describe Puppet::Resource::Catalog::Compiler do
|
|
133
160
|
before do
|
134
161
|
Facter.stubs(:value).returns "something"
|
135
162
|
@compiler = Puppet::Resource::Catalog::Compiler.new
|
136
|
-
@request =
|
163
|
+
@request = Puppet::Indirector::Request.new(:catalog, :find, "hostname", nil)
|
137
164
|
|
138
165
|
@facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386")
|
139
166
|
Puppet::Node::Facts.indirection.stubs(:save).returns(nil)
|
@@ -40,7 +40,7 @@ shared_examples_for "Indirection Delegator" do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
request =
|
43
|
+
request = Puppet::Indirector::Request.new(:indirection, :find, "me", nil)
|
44
44
|
|
45
45
|
@indirection.stubs(:request).returns request
|
46
46
|
|
@@ -101,6 +101,16 @@ shared_examples_for "Delegation Authorizer" do
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
+
shared_examples_for "Request validator" do
|
105
|
+
it "asks the terminus to validate the request" do
|
106
|
+
@terminus.expects(:validate).raises(Puppet::Indirector::ValidationError, "Invalid")
|
107
|
+
@terminus.expects(@method).never
|
108
|
+
expect {
|
109
|
+
@indirection.send(@method, "key")
|
110
|
+
}.to raise_error Puppet::Indirector::ValidationError
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
104
114
|
describe Puppet::Indirector::Indirection do
|
105
115
|
describe "when initializing" do
|
106
116
|
# (LAK) I've no idea how to test this, really.
|
@@ -141,6 +151,7 @@ describe Puppet::Indirector::Indirection do
|
|
141
151
|
before :each do
|
142
152
|
@terminus_class = mock 'terminus_class'
|
143
153
|
@terminus = mock 'terminus'
|
154
|
+
@terminus.stubs(:validate)
|
144
155
|
@terminus_class.stubs(:new).returns(@terminus)
|
145
156
|
@cache = stub 'cache', :name => "mycache"
|
146
157
|
@cache_class = mock 'cache_class'
|
@@ -211,6 +222,7 @@ describe Puppet::Indirector::Indirection do
|
|
211
222
|
|
212
223
|
it_should_behave_like "Indirection Delegator"
|
213
224
|
it_should_behave_like "Delegation Authorizer"
|
225
|
+
it_should_behave_like "Request validator"
|
214
226
|
|
215
227
|
it "should return the results of the delegation" do
|
216
228
|
@terminus.expects(:find).returns(@instance)
|
@@ -384,6 +396,7 @@ describe Puppet::Indirector::Indirection do
|
|
384
396
|
|
385
397
|
it_should_behave_like "Indirection Delegator"
|
386
398
|
it_should_behave_like "Delegation Authorizer"
|
399
|
+
it_should_behave_like "Request validator"
|
387
400
|
|
388
401
|
it "should return true if the head method returned true" do
|
389
402
|
@terminus.expects(:head).returns(true)
|
@@ -501,6 +514,7 @@ describe Puppet::Indirector::Indirection do
|
|
501
514
|
|
502
515
|
it_should_behave_like "Indirection Delegator"
|
503
516
|
it_should_behave_like "Delegation Authorizer"
|
517
|
+
it_should_behave_like "Request validator"
|
504
518
|
|
505
519
|
it "should return the result of removing the instance" do
|
506
520
|
@terminus.stubs(:destroy).returns "yayness"
|
@@ -539,6 +553,7 @@ describe Puppet::Indirector::Indirection do
|
|
539
553
|
|
540
554
|
it_should_behave_like "Indirection Delegator"
|
541
555
|
it_should_behave_like "Delegation Authorizer"
|
556
|
+
it_should_behave_like "Request validator"
|
542
557
|
|
543
558
|
it "should set the expiration date on any instances without one set" do
|
544
559
|
@terminus.stubs(:search).returns([@instance])
|
@@ -707,6 +722,7 @@ describe Puppet::Indirector::Indirection do
|
|
707
722
|
before do
|
708
723
|
@indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
|
709
724
|
@terminus = mock 'terminus'
|
725
|
+
@terminus.stubs(:validate)
|
710
726
|
@terminus_class = stub 'terminus class', :new => @terminus
|
711
727
|
end
|
712
728
|
|
@@ -9,6 +9,10 @@ describe Puppet::Indirector::Terminus do
|
|
9
9
|
class Puppet::AbstractConcept
|
10
10
|
extend Puppet::Indirector
|
11
11
|
indirects :abstract_concept
|
12
|
+
attr_accessor :name
|
13
|
+
def initialize(name = "name")
|
14
|
+
@name = name
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
class Puppet::AbstractConcept::Freedom < Puppet::Indirector::Code
|
@@ -23,6 +27,7 @@ describe Puppet::Indirector::Terminus do
|
|
23
27
|
let :terminus_class do Puppet::AbstractConcept::Freedom end
|
24
28
|
let :terminus do terminus_class.new end
|
25
29
|
let :indirection do Puppet::AbstractConcept.indirection end
|
30
|
+
let :model do Puppet::AbstractConcept end
|
26
31
|
|
27
32
|
it "should provide a method for setting terminus class documentation" do
|
28
33
|
terminus_class.should respond_to(:desc)
|
@@ -216,4 +221,44 @@ describe Puppet::Indirector::Terminus do
|
|
216
221
|
Puppet::Indirector::Terminus.terminus_classes('my_stuff').should == [:baz, :marathon]
|
217
222
|
end
|
218
223
|
end
|
224
|
+
|
225
|
+
describe "when validating a request" do
|
226
|
+
let :request do
|
227
|
+
Puppet::Indirector::Request.new(indirection.name, :find, "the_key", instance)
|
228
|
+
end
|
229
|
+
|
230
|
+
describe "`instance.name` does not match the key in the request" do
|
231
|
+
let(:instance) { model.new("wrong_key") }
|
232
|
+
|
233
|
+
it "raises an error " do
|
234
|
+
expect {
|
235
|
+
terminus.validate(request)
|
236
|
+
}.to raise_error(
|
237
|
+
Puppet::Indirector::ValidationError,
|
238
|
+
/Instance name .* does not match requested key/
|
239
|
+
)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "`instance` is not an instance of the model class" do
|
244
|
+
let(:instance) { mock "instance" }
|
245
|
+
|
246
|
+
it "raises an error" do
|
247
|
+
expect {
|
248
|
+
terminus.validate(request)
|
249
|
+
}.to raise_error(
|
250
|
+
Puppet::Indirector::ValidationError,
|
251
|
+
/Invalid instance type/
|
252
|
+
)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe "the instance key and class match the request key and model class" do
|
257
|
+
let(:instance) { model.new("the_key") }
|
258
|
+
|
259
|
+
it "passes" do
|
260
|
+
terminus.validate(request)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
219
264
|
end
|
@@ -78,6 +78,18 @@ describe Puppet::Network::AuthConfig do
|
|
78
78
|
@authconfig.rights['/'].should be_empty
|
79
79
|
@authconfig.rights['/'].authentication.should be_false
|
80
80
|
end
|
81
|
+
|
82
|
+
it '(CVE-2013-2275) allows report submission only for the node matching the certname by default' do
|
83
|
+
acl = {
|
84
|
+
:acl => "~ ^\/report\/([^\/]+)$",
|
85
|
+
:method => :save,
|
86
|
+
:allow => '$1',
|
87
|
+
:authenticated => true
|
88
|
+
}
|
89
|
+
@authconfig.stubs(:mk_acl)
|
90
|
+
@authconfig.expects(:mk_acl).with(acl)
|
91
|
+
@authconfig.insert_default_acl
|
92
|
+
end
|
81
93
|
end
|
82
94
|
|
83
95
|
describe "when checking authorization" do
|
@@ -11,6 +11,10 @@ describe Puppet::Network::Authorization do
|
|
11
11
|
|
12
12
|
describe "when creating an authconfig object" do
|
13
13
|
it "creates default ACL entries if no file has been read" do
|
14
|
+
# Other tests may have created an authconfig, so we have to undo that.
|
15
|
+
Puppet::Network::AuthConfigLoader.instance_variable_set(:@auth_config, nil)
|
16
|
+
Puppet::Network::AuthConfigLoader.instance_variable_set(:@auth_config_file, nil)
|
17
|
+
|
14
18
|
Puppet::Network::AuthConfigParser.expects(:new_from_file).raises Errno::ENOENT
|
15
19
|
Puppet::Network::AuthConfig.any_instance.expects(:insert_default_acl)
|
16
20
|
|
@@ -55,15 +55,15 @@ describe "Puppet Network Format" do
|
|
55
55
|
@yaml.render_multiple(instances).should == "foo"
|
56
56
|
end
|
57
57
|
|
58
|
-
it "should
|
58
|
+
it "should safely load YAML when interning" do
|
59
59
|
text = "foo"
|
60
|
-
YAML.expects(:
|
60
|
+
YAML.expects(:safely_load).with("foo").returns "bar"
|
61
61
|
@yaml.intern(String, text).should == "bar"
|
62
62
|
end
|
63
63
|
|
64
|
-
it "should
|
64
|
+
it "should safely load YAML when interning multiples" do
|
65
65
|
text = "foo"
|
66
|
-
YAML.expects(:
|
66
|
+
YAML.expects(:safely_load).with("foo").returns "bar"
|
67
67
|
@yaml.intern_multiple(String, text).should == "bar"
|
68
68
|
end
|
69
69
|
end
|
@@ -120,10 +120,10 @@ describe "Puppet Network Format" do
|
|
120
120
|
@yaml.intern_multiple(String, text).should == "bar"
|
121
121
|
end
|
122
122
|
|
123
|
-
it "should decode by base64 decoding, uncompressing and Yaml loading" do
|
123
|
+
it "should decode by base64 decoding, uncompressing and safely Yaml loading" do
|
124
124
|
Base64.expects(:decode64).with("zorg").returns "foo"
|
125
125
|
Zlib::Inflate.expects(:inflate).with("foo").returns "baz"
|
126
|
-
YAML.expects(:
|
126
|
+
YAML.expects(:safely_load).with("baz").returns "bar"
|
127
127
|
@yaml.decode("zorg").should == "bar"
|
128
128
|
end
|
129
129
|
|
@@ -90,7 +90,6 @@ describe Puppet::Network::HTTP::Connection do
|
|
90
90
|
|
91
91
|
it { should be_use_ssl }
|
92
92
|
its(:cert) { should be_nil }
|
93
|
-
its(:cert_store) { should be_nil }
|
94
93
|
its(:ca_file) { should be_nil }
|
95
94
|
its(:key) { should be_nil }
|
96
95
|
its(:verify_mode) { should == OpenSSL::SSL::VERIFY_NONE }
|
@@ -137,6 +137,31 @@ describe Puppet::Network::HTTP::Handler do
|
|
137
137
|
@handler.request_format(@request).should == "s"
|
138
138
|
end
|
139
139
|
|
140
|
+
it "should deserialize YAML parameters" do
|
141
|
+
params = {'my_param' => [1,2,3].to_yaml}
|
142
|
+
|
143
|
+
decoded_params = @handler.send(:decode_params, params)
|
144
|
+
|
145
|
+
decoded_params.should == {:my_param => [1,2,3]}
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should accept YAML parameters with !ruby/hash tags on Ruby 1.8", :if => RUBY_VERSION =~ /^1\.8/ do
|
149
|
+
params = {'my_param' => "--- !ruby/hash:Array {}"}
|
150
|
+
|
151
|
+
decoded_params = @handler.send(:decode_params, params)
|
152
|
+
|
153
|
+
decoded_params[:my_param].should be_an(Array)
|
154
|
+
end
|
155
|
+
|
156
|
+
# These are only dangerous with Psych, which is Ruby 1.9-only. Since
|
157
|
+
# there's no real way to change the yamler in Puppet, assume that 1.9 means
|
158
|
+
# Psych, especially in tests.
|
159
|
+
it "should fail if YAML parameters have !ruby/hash tags on Ruby 1.9", :unless => RUBY_VERSION =~ /^1\.8/ do
|
160
|
+
params = {'my_param' => "--- !ruby/hash:Array {}"}
|
161
|
+
|
162
|
+
expect { @handler.send(:decode_params, params) }.to raise_error(ArgumentError, /Illegal YAML mapping found/)
|
163
|
+
end
|
164
|
+
|
140
165
|
describe "when finding a model instance" do
|
141
166
|
before do
|
142
167
|
@indirection.stubs(:find).returns @result
|
@@ -111,6 +111,23 @@ describe "Puppet::Network::HTTP::RackREST", :if => Puppet.features.rack? do
|
|
111
111
|
@handler.set_response(@response, @file, 200)
|
112
112
|
end
|
113
113
|
end
|
114
|
+
|
115
|
+
it "should ensure the body has been read on success" do
|
116
|
+
req = mk_req('/production/report/foo', :method => 'PUT')
|
117
|
+
req.body.expects(:read).at_least_once
|
118
|
+
|
119
|
+
Puppet::Transaction::Report.stubs(:save)
|
120
|
+
|
121
|
+
@handler.process(req, @response)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should ensure the body has been partially read on failure" do
|
125
|
+
req = mk_req('/production/report/foo')
|
126
|
+
req.body.expects(:read).with(1)
|
127
|
+
req.stubs(:check_authorization).raises(Exception)
|
128
|
+
|
129
|
+
@handler.process(req, @response)
|
130
|
+
end
|
114
131
|
end
|
115
132
|
|
116
133
|
describe "and determining the request parameters" do
|
@@ -241,6 +241,10 @@ describe Puppet::Network::HTTP::WEBrick do
|
|
241
241
|
server.setup_ssl[:SSLEnable].should be_true
|
242
242
|
end
|
243
243
|
|
244
|
+
it "should reject SSLv2" do
|
245
|
+
server.setup_ssl[:SSLOptions].should == OpenSSL::SSL::OP_NO_SSLv2
|
246
|
+
end
|
247
|
+
|
244
248
|
it "should configure the verification method as 'OpenSSL::SSL::VERIFY_PEER'" do
|
245
249
|
server.setup_ssl[:SSLVerifyClient].should == OpenSSL::SSL::VERIFY_PEER
|
246
250
|
end
|
@@ -6,58 +6,29 @@ describe "the inline_template function" do
|
|
6
6
|
Puppet::Parser::Functions.autoloader.loadall
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@scope = Puppet::Parser::Scope.new(compiler)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should exist" do
|
16
|
-
Puppet::Parser::Functions.function("inline_template").should == "function_inline_template"
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should create a TemplateWrapper when called" do
|
20
|
-
tw = stub_everything 'template_wrapper'
|
9
|
+
let(:node) { Puppet::Node.new('localhost') }
|
10
|
+
let(:compiler) { Puppet::Parser::Compiler.new(node) }
|
11
|
+
let(:scope) { Puppet::Parser::Scope.new(compiler) }
|
21
12
|
|
22
|
-
|
23
|
-
|
24
|
-
@scope.function_inline_template(["test"])
|
13
|
+
it "should concatenate template wrapper outputs for multiple templates" do
|
14
|
+
inline_template("template1", "template2").should == "template1template2"
|
25
15
|
end
|
26
16
|
|
27
|
-
it "should
|
28
|
-
|
29
|
-
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
|
30
|
-
|
31
|
-
tw.expects(:result).with("test")
|
32
|
-
|
33
|
-
@scope.function_inline_template(["test"])
|
17
|
+
it "should raise an error if the template raises an error" do
|
18
|
+
expect { inline_template("<% raise 'error' %>") }.to raise_error(Puppet::ParseError)
|
34
19
|
end
|
35
20
|
|
36
|
-
it "
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
tw.expects(:result).returns("template contents evaluated")
|
41
|
-
|
42
|
-
@scope.function_inline_template(["test"]).should == "template contents evaluated"
|
21
|
+
it "is not interfered with by a variable called 'string' (#14093)" do
|
22
|
+
scope['string'] = "this is a variable"
|
23
|
+
inline_template("this is a template").should == "this is a template"
|
43
24
|
end
|
44
25
|
|
45
|
-
it "
|
46
|
-
|
47
|
-
|
48
|
-
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
|
49
|
-
tw1.stubs(:result).returns("result1")
|
50
|
-
tw2.stubs(:result).returns("result2")
|
51
|
-
|
52
|
-
@scope.function_inline_template(["1","2"]).should == "result1result2"
|
26
|
+
it "has access to a variable called 'string' (#14093)" do
|
27
|
+
scope['string'] = "this is a variable"
|
28
|
+
inline_template("string was: <%= @string %>").should == "string was: this is a variable"
|
53
29
|
end
|
54
30
|
|
55
|
-
|
56
|
-
|
57
|
-
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
|
58
|
-
tw.stubs(:result).raises
|
59
|
-
|
60
|
-
lambda { @scope.function_inline_template(["1"]) }.should raise_error(Puppet::ParseError)
|
31
|
+
def inline_template(*templates)
|
32
|
+
scope.function_inline_template(templates)
|
61
33
|
end
|
62
|
-
|
63
34
|
end
|
@@ -10,38 +10,7 @@ describe "the template function" do
|
|
10
10
|
let :compiler do Puppet::Parser::Compiler.new(node) end
|
11
11
|
let :scope do Puppet::Parser::Scope.new(compiler) end
|
12
12
|
|
13
|
-
it "
|
14
|
-
Puppet::Parser::Functions.function("template").should == "function_template"
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should create a TemplateWrapper when called" do
|
18
|
-
tw = stub_everything 'template_wrapper'
|
19
|
-
|
20
|
-
Puppet::Parser::TemplateWrapper.expects(:new).returns(tw)
|
21
|
-
|
22
|
-
scope.function_template(["test"])
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should give the template filename to the TemplateWrapper" do
|
26
|
-
tw = stub_everything 'template_wrapper'
|
27
|
-
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
|
28
|
-
|
29
|
-
tw.expects(:file=).with("test")
|
30
|
-
|
31
|
-
scope.function_template(["test"])
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should return what TemplateWrapper.result returns" do
|
35
|
-
tw = stub_everything 'template_wrapper'
|
36
|
-
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
|
37
|
-
tw.stubs(:file=).with("test")
|
38
|
-
|
39
|
-
tw.expects(:result).returns("template contents evaluated")
|
40
|
-
|
41
|
-
scope.function_template(["test"]).should == "template contents evaluated"
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should concatenate template wrapper outputs for multiple templates" do
|
13
|
+
it "concatenates outputs for multiple templates" do
|
45
14
|
tw1 = stub_everything "template_wrapper1"
|
46
15
|
tw2 = stub_everything "template_wrapper2"
|
47
16
|
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw1,tw2)
|
@@ -53,7 +22,7 @@ describe "the template function" do
|
|
53
22
|
scope.function_template(["1","2"]).should == "result1result2"
|
54
23
|
end
|
55
24
|
|
56
|
-
it "
|
25
|
+
it "raises an error if the template raises an error" do
|
57
26
|
tw = stub_everything 'template_wrapper'
|
58
27
|
Puppet::Parser::TemplateWrapper.stubs(:new).returns(tw)
|
59
28
|
tw.stubs(:result).raises
|
@@ -63,40 +32,58 @@ describe "the template function" do
|
|
63
32
|
}.to raise_error(Puppet::ParseError, /Failed to parse template/)
|
64
33
|
end
|
65
34
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
35
|
+
context "when accessing scope variables via method calls (deprecated)" do
|
36
|
+
it "raises an error when accessing an undefined variable" do
|
37
|
+
expect {
|
38
|
+
eval_template("template <%= deprecated %>")
|
39
|
+
}.to raise_error(Puppet::ParseError, /Could not find value for 'deprecated'/)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "looks up the value from the scope" do
|
43
|
+
scope["deprecated"] = "deprecated value"
|
44
|
+
eval_template("template <%= deprecated %>").should == "template deprecated value"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "still has access to Kernel methods" do
|
48
|
+
expect { eval_template("<%= binding %>") }.to_not raise_error
|
49
|
+
end
|
70
50
|
end
|
71
51
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
52
|
+
context "when accessing scope variables as instance variables" do
|
53
|
+
it "has access to values" do
|
54
|
+
scope['scope_var'] = "value"
|
55
|
+
eval_template("<%= @scope_var %>").should == "value"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "get nil accessing a variable that does not exist" do
|
59
|
+
eval_template("<%= @not_defined.nil? %>").should == "true"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "get nil accessing a variable that is undef" do
|
63
|
+
scope['undef_var'] = :undef
|
64
|
+
eval_template("<%= @undef_var.nil? %>").should == "true"
|
65
|
+
end
|
76
66
|
end
|
77
67
|
|
78
|
-
it "
|
79
|
-
scope[
|
80
|
-
eval_template("
|
68
|
+
it "is not interfered with by having a variable named 'string' (#14093)" do
|
69
|
+
scope['string'] = "this output should not be seen"
|
70
|
+
eval_template("some text that is static").should == "some text that is static"
|
81
71
|
end
|
82
72
|
|
83
|
-
it "
|
84
|
-
|
73
|
+
it "has access to a variable named 'string' (#14093)" do
|
74
|
+
scope['string'] = "the string value"
|
75
|
+
eval_template("string was: <%= @string %>").should == "string was: the string value"
|
85
76
|
end
|
86
77
|
|
87
|
-
it "
|
88
|
-
scope['myvar'] = 'this is yayness'
|
78
|
+
it "does not have direct access to Scope#lookupvar" do
|
89
79
|
expect {
|
90
80
|
eval_template("<%= lookupvar('myvar') %>")
|
91
|
-
}.to raise_error(Puppet::ParseError)
|
81
|
+
}.to raise_error(Puppet::ParseError, /Could not find value for 'lookupvar'/)
|
92
82
|
end
|
93
83
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
eval_template("<%= @yayness %>").should == output
|
99
|
-
}.to_not raise_error
|
100
|
-
end
|
84
|
+
def eval_template(content)
|
85
|
+
File.stubs(:read).with("template").returns(content)
|
86
|
+
Puppet::Parser::Files.stubs(:find_template).returns("template")
|
87
|
+
scope.function_template(['template'])
|
101
88
|
end
|
102
89
|
end
|