3
require 'puppet/ssl/host'
4
require 'puppet/indirector/certificate_status'
7
describe "Puppet::Indirector::CertificateStatus::File" do
8
include PuppetSpec::Files
11
Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true
12
@terminus = Puppet::SSL::Host.indirection.terminus(:file)
14
@tmpdir = tmpdir("certificate_status_ca_testing")
15
Puppet[:confdir] = @tmpdir
16
Puppet[:vardir] = @tmpdir
18
# localcacert is where each client stores the CA certificate
19
# cacert is where the master stores the CA certificate
20
# Since we need to play the role of both for testing we need them to be the same and exist
21
Puppet[:cacert] = Puppet[:localcacert]
24
def generate_csr(host)
26
csr = Puppet::SSL::CertificateRequest.new(host.name)
27
csr.generate(host.key.content)
28
Puppet::SSL::CertificateRequest.indirection.save(csr)
32
host.desired_state = "signed"
33
@terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host))
36
def generate_signed_cert(host)
40
@terminus.find(Puppet::Indirector::Request.new(:certificate_status, :find, host.name, host))
43
def generate_revoked_cert(host)
44
generate_signed_cert(host)
46
host.desired_state = "revoked"
48
@terminus.save(Puppet::Indirector::Request.new(:certificate_status, :save, host.name, host))
51
it "should be a terminus on SSL::Host" do
52
@terminus.should be_instance_of(Puppet::Indirector::CertificateStatus::File)
55
it "should create a CA instance if none is present" do
56
@terminus.ca.should be_instance_of(Puppet::SSL::CertificateAuthority)
59
describe "when creating the CA" do
60
it "should fail if it is not a valid CA" do
61
Puppet::SSL::CertificateAuthority.expects(:ca?).returns false
62
lambda { @terminus.ca }.should raise_error(ArgumentError, "This process is not configured as a certificate authority")
66
it "should be indirected with the name 'certificate_status'" do
67
Puppet::SSL::Host.indirection.name.should == :certificate_status
70
describe "when finding" do
72
@host = Puppet::SSL::Host.new("foo")
73
Puppet.settings.use(:main)
76
it "should return the Puppet::SSL::Host when a CSR exists for the host" do
78
request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
80
retrieved_host = @terminus.find(request)
82
retrieved_host.name.should == @host.name
83
retrieved_host.certificate_request.content.to_s.chomp.should == @host.certificate_request.content.to_s.chomp
86
it "should return the Puppet::SSL::Host when a public key exist for the host" do
87
generate_signed_cert(@host)
88
request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
90
retrieved_host = @terminus.find(request)
92
retrieved_host.name.should == @host.name
93
retrieved_host.certificate.content.to_s.chomp.should == @host.certificate.content.to_s.chomp
96
it "should return nil when neither a CSR nor public key exist for the host" do
97
request = Puppet::Indirector::Request.new(:certificate_status, :find, "foo", @host)
98
@terminus.find(request).should == nil
102
describe "when saving" do
104
@host = Puppet::SSL::Host.new("foobar")
105
Puppet.settings.use(:main)
108
describe "when signing a cert" do
110
@host.desired_state = "signed"
111
@request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host)
114
it "should fail if no CSR is on disk" do
115
lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /certificate request/)
118
it "should sign the on-disk CSR when it is present" do
119
signed_host = generate_signed_cert(@host)
121
signed_host.state.should == "signed"
122
Puppet::SSL::Certificate.indirection.find("foobar").should be_instance_of(Puppet::SSL::Certificate)
126
describe "when revoking a cert" do
128
@request = Puppet::Indirector::Request.new(:certificate_status, :save, "foobar", @host)
131
it "should fail if no certificate is on disk" do
132
@host.desired_state = "revoked"
133
lambda { @terminus.save(@request) }.should raise_error(Puppet::Error, /Cannot revoke/)
136
it "should revoke the certificate when it is present" do
137
generate_revoked_cert(@host)
139
@host.state.should == 'revoked'
144
describe "when deleting" do
146
Puppet.settings.use(:main)
149
it "should not delete anything if no certificate, request, or key is on disk" do
150
host = Puppet::SSL::Host.new("clean_me")
151
request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_me", host)
152
@terminus.destroy(request).should == "Nothing was deleted"
155
it "should clean certs, cert requests, keys" do
156
signed_host = Puppet::SSL::Host.new("clean_signed_cert")
157
generate_signed_cert(signed_host)
158
signed_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_signed_cert", signed_host)
159
@terminus.destroy(signed_request).should == "Deleted for clean_signed_cert: Puppet::SSL::Certificate, Puppet::SSL::Key"
161
requested_host = Puppet::SSL::Host.new("clean_csr")
162
generate_csr(requested_host)
163
csr_request = Puppet::Indirector::Request.new(:certificate_status, :delete, "clean_csr", requested_host)
164
@terminus.destroy(csr_request).should == "Deleted for clean_csr: Puppet::SSL::CertificateRequest, Puppet::SSL::Key"
168
describe "when searching" do
169
it "should return a list of all hosts with certificate requests, signed certs, or revoked certs" do
170
Puppet.settings.use(:main)
172
signed_host = Puppet::SSL::Host.new("signed_host")
173
generate_signed_cert(signed_host)
175
requested_host = Puppet::SSL::Host.new("requested_host")
176
generate_csr(requested_host)
178
revoked_host = Puppet::SSL::Host.new("revoked_host")
179
generate_revoked_cert(revoked_host)
181
retrieved_hosts = @terminus.search(Puppet::Indirector::Request.new(:certificate_status, :search, "all", signed_host))
183
results = retrieved_hosts.map {|h| [h.name, h.state]}.sort{ |h,i| h[0] <=> i[0] }
184
results.should == [["ca","signed"],["requested_host","requested"],["revoked_host","revoked"],["signed_host","signed"]]