diff options
author | Luke Kanies <luke@madstop.com> | 2008-05-05 17:10:07 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-05-05 17:10:07 -0500 |
commit | 67dc268fae0489de93f247b08fdaf7b1eec0e15d (patch) | |
tree | 727206889dcccab3d9d3292726e87a663ae539f9 | |
parent | 6356c043a44c771d707750f96f7660a1093be9ac (diff) | |
download | puppet-67dc268fae0489de93f247b08fdaf7b1eec0e15d.tar.gz puppet-67dc268fae0489de93f247b08fdaf7b1eec0e15d.tar.xz puppet-67dc268fae0489de93f247b08fdaf7b1eec0e15d.zip |
The CA now initializes itself.
I realized that it never made sense to have a CA
that didn't know how to initialize itself, so we
now have a singleton method for the CA, and it also
automatically initializes itself.
-rw-r--r-- | lib/puppet/ssl/certificate_authority.rb | 25 | ||||
-rwxr-xr-x | spec/integration/ssl/certificate_authority.rb | 2 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_authority.rb | 89 |
3 files changed, 103 insertions, 13 deletions
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb index 42981424e..d336692a6 100644 --- a/lib/puppet/ssl/certificate_authority.rb +++ b/lib/puppet/ssl/certificate_authority.rb @@ -124,6 +124,19 @@ class Puppet::SSL::CertificateAuthority end end + # If this process can function as a CA, then return a singleton + # instance. + def self.instance + return nil unless Puppet[:ca] + return nil unless Puppet[:name] == "puppetmasterd" + + unless defined?(@instance) and @instance + @instance = new + end + + @instance + end + attr_reader :name, :host # Create and run an applicator. I wanted to build an interface where you could do @@ -192,6 +205,8 @@ class Puppet::SSL::CertificateAuthority @name = Puppet[:certname] @host = Puppet::SSL::Host.new(Puppet::SSL::Host.ca_name) + + setup() end # Retrieve (or create, if necessary) our inventory manager. @@ -267,6 +282,14 @@ class Puppet::SSL::CertificateAuthority crl.revoke(serial, host.key.content) end + # This initializes our CA so it actually works. This should be a private + # method, except that you can't any-instance stub private methods, which is + # *awesome*. This method only really exists to provide a stub-point during + # testing. + def setup + generate_ca_certificate unless @host.certificate + end + # Sign a given certificate request. def sign(hostname, cert_type = :server, self_signing_csr = nil) # This is a self-signed certificate @@ -274,8 +297,6 @@ class Puppet::SSL::CertificateAuthority csr = self_signing_csr issuer = csr.content else - generate_ca_certificate unless host.certificate - unless csr = Puppet::SSL::CertificateRequest.find(hostname) raise ArgumentError, "Could not find certificate request for %s" % hostname end diff --git a/spec/integration/ssl/certificate_authority.rb b/spec/integration/ssl/certificate_authority.rb index f7eb0f46a..447dabe43 100755 --- a/spec/integration/ssl/certificate_authority.rb +++ b/spec/integration/ssl/certificate_authority.rb @@ -32,6 +32,8 @@ describe Puppet::SSL::CertificateAuthority do Puppet::SSL::Key.indirection.clear_cache Puppet::SSL::Certificate.indirection.clear_cache Puppet::SSL::CertificateRequest.indirection.clear_cache + + Puppet::SSL::CertificateAuthority.instance_variable_set("@instance", nil) } it "should create a CA host" do diff --git a/spec/unit/ssl/certificate_authority.rb b/spec/unit/ssl/certificate_authority.rb index 424f47512..0cb2f2f1c 100755 --- a/spec/unit/ssl/certificate_authority.rb +++ b/spec/unit/ssl/certificate_authority.rb @@ -27,12 +27,69 @@ describe "a normal interface method", :shared => true do end describe Puppet::SSL::CertificateAuthority do + after do + # Clear out the var, yay unit tests. + Puppet::SSL::CertificateAuthority.instance_variable_set("@instance", nil) + Puppet.settings.clearused + end + + it "should have a class method for returning a singleton instance" do + Puppet::SSL::CertificateAuthority.should respond_to(:instance) + end + + describe "when finding an existing instance" do + describe "and the host is a CA host and the proces name is 'puppetmasterd'" do + before do + Puppet.settings.stubs(:value).with(:ca).returns true + Puppet.settings.stubs(:value).with(:name).returns "puppetmasterd" + + @ca = mock('ca') + Puppet::SSL::CertificateAuthority.stubs(:new).returns @ca + end + + after do + # Clear out the var, yay unit tests. + Puppet::SSL::CertificateAuthority.instance_variable_set("@instance", nil) + end + + it "should return an instance" do + Puppet::SSL::CertificateAuthority.instance.should equal(@ca) + end + + it "should always return the same instance" do + Puppet::SSL::CertificateAuthority.instance.should equal(Puppet::SSL::CertificateAuthority.instance) + end + end + + describe "and the host is not a CA host" do + it "should return nil" do + Puppet.settings.stubs(:value).with(:ca).returns false + Puppet.settings.stubs(:value).with(:name).returns "puppetmasterd" + + ca = mock('ca') + Puppet::SSL::CertificateAuthority.expects(:new).never + Puppet::SSL::CertificateAuthority.instance.should be_nil + end + end + + describe "and the process name is not 'puppetmasterd'" do + it "should return nil" do + Puppet.settings.stubs(:value).with(:ca).returns true + Puppet.settings.stubs(:value).with(:name).returns "puppetd" + + ca = mock('ca') + Puppet::SSL::CertificateAuthority.expects(:new).never + Puppet::SSL::CertificateAuthority.instance.should be_nil + end + end + end + describe "when initializing" do before do Puppet.settings.stubs(:use) Puppet.settings.stubs(:value).returns "whatever" - Puppet::SSL::CertificateAuthority.any_instance.stubs(:generate_ca_certificate) + Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) end it "should always set its name to the value of :certname" do @@ -60,6 +117,24 @@ describe Puppet::SSL::CertificateAuthority do Puppet::SSL::CertificateAuthority.new.inventory.should == "inventory" end + + it "should make sure the CA is set up" do + Puppet::SSL::CertificateAuthority.any_instance.expects(:setup) + + Puppet::SSL::CertificateAuthority.new + end + end + + describe "when setting itself up" do + it "should generate the CA certificate if it does not have one" do + host = stub 'host' + Puppet::SSL::Host.stubs(:new).returns host + + host.expects(:certificate).returns nil + + Puppet::SSL::CertificateAuthority.any_instance.expects(:generate_ca_certificate) + Puppet::SSL::CertificateAuthority.new + end end describe "when retrieving the certificate revocation list" do @@ -67,7 +142,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings.stubs(:use) Puppet.settings.stubs(:value).returns "whatever" - Puppet::SSL::CertificateAuthority.any_instance.stubs(:generate_ca_certificate) + Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) @ca = Puppet::SSL::CertificateAuthority.new end @@ -124,6 +199,7 @@ describe Puppet::SSL::CertificateAuthority do Puppet.settings.stubs(:use) Puppet.settings.stubs(:value).returns "whatever" + Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) @ca = Puppet::SSL::CertificateAuthority.new @host = stub 'host', :key => mock("key"), :name => "hostname" @@ -298,15 +374,6 @@ describe Puppet::SSL::CertificateAuthority do @cert.stubs :save end - it "should generate a self-signed certificate if its Host instance has no certificate" do - cert = stub 'ca_certificate', :content => "mock_cert" - - @ca.host.expects(:certificate).times(2).returns(nil).then.returns cert - @ca.expects(:generate_ca_certificate) - - @ca.sign(@name) - end - it "should use a certificate type of :server" do Puppet::SSL::CertificateFactory.expects(:new).with do |*args| args[0] == :server |