1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
#!/usr/bin/env rspec
require 'spec_helper'
require 'puppet/indirector/ssl_file'
describe Puppet::Indirector::SslFile do
include PuppetSpec::Files
before :all do
@indirection = stub 'indirection', :name => :testing, :model => @model
Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
module Testing; end
@file_class = class Testing::MyType < Puppet::Indirector::SslFile
self
end
end
before :each do
@model = mock 'model'
@setting = :certdir
@file_class.store_in @setting
@path = make_absolute("/thisdoesntexist/my_directory")
Puppet[:noop] = false
Puppet[@setting] = @path
Puppet[:trace] = false
end
it "should use :main and :ssl upon initialization" do
Puppet.settings.expects(:use).with(:main, :ssl)
@file_class.new
end
it "should return a nil collection directory if no directory setting has been provided" do
@file_class.store_in nil
@file_class.collection_directory.should be_nil
end
it "should return a nil file location if no location has been provided" do
@file_class.store_at nil
@file_class.file_location.should be_nil
end
it "should fail if no store directory or file location has been set" do
@file_class.store_in nil
@file_class.store_at nil
FileTest.expects(:exists?).with(File.dirname(@path)).at_least(0).returns(true)
Dir.stubs(:mkdir).with(@path)
lambda { @file_class.new }.should raise_error(Puppet::DevError, /No file or directory setting provided/)
end
describe "when managing ssl files" do
before do
Puppet.settings.stubs(:use)
@searcher = @file_class.new
@cert = stub 'certificate', :name => "myname"
@certpath = File.join(@path, "myname.pem")
@request = stub 'request', :key => @cert.name, :instance => @cert
end
it "should consider the file a ca file if the name is equal to what the SSL::Host class says is the CA name" do
Puppet::SSL::Host.expects(:ca_name).returns "amaca"
@searcher.should be_ca("amaca")
end
describe "when choosing the location for certificates" do
it "should set them at the ca setting's path if a ca setting is available and the name resolves to the CA name" do
@file_class.store_in nil
@file_class.store_at :mysetting
@file_class.store_ca_at :casetting
Puppet.settings.stubs(:value).with(:casetting).returns "/ca/file"
@searcher.expects(:ca?).with(@cert.name).returns true
@searcher.path(@cert.name).should == "/ca/file"
end
it "should set them at the file location if a file setting is available" do
@file_class.store_in nil
@file_class.store_at :mysetting
Puppet.settings.stubs(:value).with(:mysetting).returns "/some/file"
@searcher.path(@cert.name).should == "/some/file"
end
it "should set them in the setting directory, with the certificate name plus '.pem', if a directory setting is available" do
@searcher.path(@cert.name).should == @certpath
end
end
describe "when finding certificates on disk" do
describe "and no certificate is present" do
before do
# Stub things so the case management bits work.
FileTest.stubs(:exist?).with(File.dirname(@certpath)).returns false
FileTest.expects(:exist?).with(@certpath).returns false
end
it "should return nil" do
@searcher.find(@request).should be_nil
end
end
describe "and a certificate is present" do
before do
FileTest.expects(:exist?).with(@certpath).returns true
end
it "should return an instance of the model, which it should use to read the certificate" do
cert = mock 'cert'
model = mock 'model'
@file_class.stubs(:model).returns model
model.expects(:new).with("myname").returns cert
cert.expects(:read).with(@certpath)
@searcher.find(@request).should equal(cert)
end
end
describe "and a certificate is present but has uppercase letters" do
before do
@request = stub 'request', :key => "myhost"
end
# This is kind of more an integration test; it's for #1382, until
# the support for upper-case certs can be removed around mid-2009.
it "should rename the existing file to the lower-case path" do
@path = @searcher.path("myhost")
FileTest.expects(:exist?).with(@path).returns(false)
dir, file = File.split(@path)
FileTest.expects(:exist?).with(dir).returns true
Dir.expects(:entries).with(dir).returns [".", "..", "something.pem", file.upcase]
File.expects(:rename).with(File.join(dir, file.upcase), @path)
cert = mock 'cert'
model = mock 'model'
@searcher.stubs(:model).returns model
@searcher.model.expects(:new).with("myhost").returns cert
cert.expects(:read).with(@path)
@searcher.find(@request)
end
end
end
describe "when saving certificates to disk" do
before do
FileTest.stubs(:directory?).returns true
FileTest.stubs(:writable?).returns true
end
it "should fail if the directory is absent" do
FileTest.expects(:directory?).with(File.dirname(@certpath)).returns false
lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
end
it "should fail if the directory is not writeable" do
FileTest.stubs(:directory?).returns true
FileTest.expects(:writable?).with(File.dirname(@certpath)).returns false
lambda { @searcher.save(@request) }.should raise_error(Puppet::Error)
end
it "should save to the path the output of converting the certificate to a string" do
fh = mock 'filehandle'
fh.expects(:print).with("mycert")
@searcher.stubs(:write).yields fh
@cert.expects(:to_s).returns "mycert"
@searcher.save(@request)
end
describe "and a directory setting is set" do
it "should use the Settings class to write the file" do
@searcher.class.store_in @setting
fh = mock 'filehandle'
fh.stubs :print
Puppet.settings.expects(:writesub).with(@setting, @certpath).yields fh
@searcher.save(@request)
end
end
describe "and a file location is set" do
it "should use the filehandle provided by the Settings" do
@searcher.class.store_at @setting
fh = mock 'filehandle'
fh.stubs :print
Puppet.settings.expects(:write).with(@setting).yields fh
@searcher.save(@request)
end
end
describe "and the name is the CA name and a ca setting is set" do
it "should use the filehandle provided by the Settings" do
@searcher.class.store_at @setting
@searcher.class.store_ca_at :castuff
Puppet.settings.stubs(:value).with(:castuff).returns "castuff stub"
fh = mock 'filehandle'
fh.stubs :print
Puppet.settings.expects(:write).with(:castuff).yields fh
@searcher.stubs(:ca?).returns true
@searcher.save(@request)
end
end
end
describe "when destroying certificates" do
describe "that do not exist" do
before do
FileTest.expects(:exist?).with(@certpath).returns false
end
it "should return false" do
@searcher.destroy(@request).should be_false
end
end
describe "that exist" do
before do
FileTest.expects(:exist?).with(@certpath).returns true
end
it "should unlink the certificate file" do
File.expects(:unlink).with(@certpath)
@searcher.destroy(@request)
end
it "should log that is removing the file" do
File.stubs(:exist?).returns true
File.stubs(:unlink)
Puppet.expects(:notice)
@searcher.destroy(@request)
end
end
end
describe "when searching for certificates" do
before do
@model = mock 'model'
@file_class.stubs(:model).returns @model
end
it "should return a certificate instance for all files that exist" do
Dir.expects(:entries).with(@path).returns %w{one.pem two.pem}
one = stub 'one', :read => nil
two = stub 'two', :read => nil
@model.expects(:new).with("one").returns one
@model.expects(:new).with("two").returns two
@searcher.search(@request).should == [one, two]
end
it "should read each certificate in using the model's :read method" do
Dir.expects(:entries).with(@path).returns %w{one.pem}
one = stub 'one'
one.expects(:read).with(File.join(@path, "one.pem"))
@model.expects(:new).with("one").returns one
@searcher.search(@request)
end
it "should skip any files that do not match /\.pem$/" do
Dir.expects(:entries).with(@path).returns %w{. .. one.pem}
one = stub 'one', :read => nil
@model.expects(:new).with("one").returns one
@searcher.search(@request)
end
end
end
end
|