summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-05-06 15:39:18 -0500
committerLuke Kanies <luke@madstop.com>2008-05-06 15:39:18 -0500
commita822ef9ce5c6d603f4a98b9dda0dbf4661528128 (patch)
treed35c546f2321b49d7be7bff0a367564ed1ca350b
parent38e2dcf35a1d9b19970d1fb253f6c09b0529e083 (diff)
Moving the CA Interface class to a separate file.
-rw-r--r--lib/puppet/ssl/certificate_authority.rb143
-rw-r--r--lib/puppet/ssl/certificate_authority/interface.rb110
-rwxr-xr-xspec/unit/ssl/certificate_authority.rb260
-rwxr-xr-xspec/unit/ssl/certificate_authority/interface.rb265
4 files changed, 414 insertions, 364 deletions
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb
index 9958575d5..9385110d2 100644
--- a/lib/puppet/ssl/certificate_authority.rb
+++ b/lib/puppet/ssl/certificate_authority.rb
@@ -14,115 +14,7 @@ class Puppet::SSL::CertificateAuthority
require 'puppet/ssl/inventory'
require 'puppet/ssl/certificate_revocation_list'
- # This class is basically a hidden class that knows how to act
- # on the CA. It's only used by the 'puppetca' executable, and its
- # job is to provide a CLI-like interface to the CA class.
- class Interface
- INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify]
-
- class InterfaceError < ArgumentError; end
-
- attr_reader :method, :subjects
-
- # Actually perform the work.
- def apply(ca)
- unless subjects or method == :list
- raise ArgumentError, "You must provide hosts or :all when using %s" % method
- end
-
- begin
- if respond_to?(method)
- return send(method, ca)
- end
-
- (subjects == :all ? ca.list : subjects).each do |host|
- ca.send(method, host)
- end
- rescue InterfaceError
- raise
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not call %s: %s" % [method, detail]
- end
- end
-
- def generate(ca)
- raise InterfaceError, "It makes no sense to generate all hosts; you must specify a list" if subjects == :all
-
- subjects.each do |host|
- ca.generate(host)
- end
- end
-
- def initialize(method, subjects)
- self.method = method
- self.subjects = subjects
- end
-
- # List the hosts.
- def list(ca)
- unless subjects
- puts ca.waiting?.join("\n")
- return nil
- end
-
- signed = ca.list
- requests = ca.waiting?
-
- if subjects == :all
- hosts = [signed, requests].flatten
- else
- hosts = subjects
- end
-
- hosts.uniq.sort.each do |host|
- if signed.include?(host)
- puts "+ " + host
- else
- puts host
- end
- end
- end
-
- # Set the method to apply.
- def method=(method)
- raise ArgumentError, "Invalid method %s to apply" % method unless INTERFACE_METHODS.include?(method)
- @method = method
- end
-
- # Print certificate information.
- def print(ca)
- (subjects == :all ? ca.list : subjects).each do |host|
- if value = ca.print(host)
- puts value
- else
- Puppet.err "Could not find certificate for %s" % host
- end
- end
- end
-
- # Sign a given certificate.
- def sign(ca)
- list = subjects == :all ? ca.waiting? : subjects
- raise InterfaceError, "No waiting certificate requests to sign" if list.empty?
- list.each do |host|
- ca.sign(host)
- end
- end
-
- # Set the list of hosts we're operating on. Also supports keywords.
- def subjects=(value)
- unless value == :all or value.is_a?(Array)
- raise ArgumentError, "Subjects must be an array or :all; not %s" % value
- end
-
- if value.is_a?(Array) and value.empty?
- value = nil
- end
-
- @subjects = value
- end
- end
+ require 'puppet/ssl/certificate_authority/interface'
# If this process can function as a CA, then return a singleton
# instance.
@@ -150,6 +42,39 @@ class Puppet::SSL::CertificateAuthority
applier.apply(self)
end
+ # FIXME autosign? should probably accept both hostnames and IP addresses
+ def autosign?(hostname)
+ # simple values are easy
+ if autosign == true or autosign == false
+ return autosign
+ end
+
+ # we only otherwise know how to handle files
+ unless autosign =~ /^\//
+ raise Puppet::Error, "Invalid autosign value %s" %
+ autosign.inspect
+ end
+
+ unless FileTest.exists?(autosign)
+ unless defined? @@warnedonautosign
+ @@warnedonautosign = true
+ Puppet.info "Autosign is enabled but %s is missing" % autosign
+ end
+ return false
+ end
+ auth = Puppet::Network::AuthStore.new
+ File.open(autosign) { |f|
+ f.each { |line|
+ next if line =~ /^\s*#/
+ next if line =~ /^\s*$/
+ auth.allow(line.chomp)
+ }
+ }
+
+ # for now, just cheat and pass a fake IP address to allowed?
+ return auth.allowed?(hostname, "127.1.1.1")
+ end
+
# Retrieve (or create, if necessary) the certificate revocation list.
def crl
unless defined?(@crl)
diff --git a/lib/puppet/ssl/certificate_authority/interface.rb b/lib/puppet/ssl/certificate_authority/interface.rb
new file mode 100644
index 000000000..b355e21f0
--- /dev/null
+++ b/lib/puppet/ssl/certificate_authority/interface.rb
@@ -0,0 +1,110 @@
+# This class is basically a hidden class that knows how to act
+# on the CA. It's only used by the 'puppetca' executable, and its
+# job is to provide a CLI-like interface to the CA class.
+class Puppet::SSL::CertificateAuthority::Interface
+ INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify]
+
+ class InterfaceError < ArgumentError; end
+
+ attr_reader :method, :subjects
+
+ # Actually perform the work.
+ def apply(ca)
+ unless subjects or method == :list
+ raise ArgumentError, "You must provide hosts or :all when using %s" % method
+ end
+
+ begin
+ if respond_to?(method)
+ return send(method, ca)
+ end
+
+ (subjects == :all ? ca.list : subjects).each do |host|
+ ca.send(method, host)
+ end
+ rescue InterfaceError
+ raise
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not call %s: %s" % [method, detail]
+ end
+ end
+
+ def generate(ca)
+ raise InterfaceError, "It makes no sense to generate all hosts; you must specify a list" if subjects == :all
+
+ subjects.each do |host|
+ ca.generate(host)
+ end
+ end
+
+ def initialize(method, subjects)
+ self.method = method
+ self.subjects = subjects
+ end
+
+ # List the hosts.
+ def list(ca)
+ unless subjects
+ puts ca.waiting?.join("\n")
+ return nil
+ end
+
+ signed = ca.list
+ requests = ca.waiting?
+
+ if subjects == :all
+ hosts = [signed, requests].flatten
+ else
+ hosts = subjects
+ end
+
+ hosts.uniq.sort.each do |host|
+ if signed.include?(host)
+ puts "+ " + host
+ else
+ puts host
+ end
+ end
+ end
+
+ # Set the method to apply.
+ def method=(method)
+ raise ArgumentError, "Invalid method %s to apply" % method unless INTERFACE_METHODS.include?(method)
+ @method = method
+ end
+
+ # Print certificate information.
+ def print(ca)
+ (subjects == :all ? ca.list : subjects).each do |host|
+ if value = ca.print(host)
+ puts value
+ else
+ Puppet.err "Could not find certificate for %s" % host
+ end
+ end
+ end
+
+ # Sign a given certificate.
+ def sign(ca)
+ list = subjects == :all ? ca.waiting? : subjects
+ raise InterfaceError, "No waiting certificate requests to sign" if list.empty?
+ list.each do |host|
+ ca.sign(host)
+ end
+ end
+
+ # Set the list of hosts we're operating on. Also supports keywords.
+ def subjects=(value)
+ unless value == :all or value.is_a?(Array)
+ raise ArgumentError, "Subjects must be an array or :all; not %s" % value
+ end
+
+ if value.is_a?(Array) and value.empty?
+ value = nil
+ end
+
+ @subjects = value
+ end
+end
+
diff --git a/spec/unit/ssl/certificate_authority.rb b/spec/unit/ssl/certificate_authority.rb
index bf8625445..12516b816 100755
--- a/spec/unit/ssl/certificate_authority.rb
+++ b/spec/unit/ssl/certificate_authority.rb
@@ -4,28 +4,6 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/ssl/certificate_authority'
-describe "a normal interface method", :shared => true do
- it "should call the method on the CA for each host specified if an array was provided" do
- @ca.expects(@method).with("host1")
- @ca.expects(@method).with("host2")
-
- @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, %w{host1 host2})
-
- @applier.apply(@ca)
- end
-
- it "should call the method on the CA for all existing certificates if :all was provided" do
- @ca.expects(:list).returns %w{host1 host2}
-
- @ca.expects(@method).with("host1")
- @ca.expects(@method).with("host2")
-
- @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :all)
-
- @applier.apply(@ca)
- end
-end
-
describe Puppet::SSL::CertificateAuthority do
after do
# Clear out the var, yay unit tests.
@@ -701,242 +679,14 @@ describe Puppet::SSL::CertificateAuthority do
end
end
end
-end
-
-describe Puppet::SSL::CertificateAuthority::Interface do
- before do
- @class = Puppet::SSL::CertificateAuthority::Interface
- end
- describe "when initializing" do
- it "should set its method using its settor" do
- @class.any_instance.expects(:method=).with(:generate)
- @class.new(:generate, :all)
- end
-
- it "should set its subjects using the settor" do
- @class.any_instance.expects(:subjects=).with(:all)
- @class.new(:generate, :all)
- end
- end
- describe "when setting the method" do
- it "should set the method" do
- @class.new(:generate, :all).method.should == :generate
- end
+ it "should have a method for triggering autosigning of available CSRs"
- it "should fail if the method isn't a member of the INTERFACE_METHODS array" do
- Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false
+ describe "when autosigning certificates" do
+ it "should do nothing if autosign is disabled"
- lambda { @class.new(:thing, :all) }.should raise_error(ArgumentError)
- end
- end
-
- describe "when setting the subjects" do
- it "should set the subjects" do
- @class.new(:generate, :all).subjects.should == :all
- end
-
- it "should fail if the subjects setting isn't :all or an array" do
- lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError)
- end
- end
+ it "should do nothing if no autosign.conf exists"
- it "should have a method for triggering the application" do
- @class.new(:generate, :all).should respond_to(:apply)
- end
-
- describe "when applying" do
- before do
- # We use a real object here, because :verify can't be stubbed, apparently.
- @ca = Object.new
- end
-
- it "should raise InterfaceErrors" do
- @applier = @class.new(:revoke, :all)
-
- @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
-
- lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
- end
-
- it "should log non-Interface failures rather than failing" do
- @applier = @class.new(:revoke, :all)
-
- @ca.expects(:list).raises ArgumentError
-
- Puppet.expects(:err)
-
- lambda { @applier.apply(@ca) }.should_not raise_error
- end
-
- describe "with an empty array specified and the method is not list" do
- it "should fail" do
- @applier = @class.new(:sign, [])
- lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
- end
- end
-
- describe ":generate" do
- it "should fail if :all was specified" do
- @applier = @class.new(:generate, :all)
- lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
- end
-
- it "should call :generate on the CA for each host specified" do
- @applier = @class.new(:generate, %w{host1 host2})
-
- @ca.expects(:generate).with("host1")
- @ca.expects(:generate).with("host2")
-
- @applier.apply(@ca)
- end
- end
-
- describe ":verify" do
- before { @method = :verify }
- #it_should_behave_like "a normal interface method"
-
- it "should call the method on the CA for each host specified if an array was provided" do
- # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
- end
-
- it "should call the method on the CA for all existing certificates if :all was provided" do
- # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
- end
- end
-
- describe ":destroy" do
- before { @method = :destroy }
- it_should_behave_like "a normal interface method"
- end
-
- describe ":revoke" do
- before { @method = :revoke }
- it_should_behave_like "a normal interface method"
- end
-
- describe ":sign" do
- describe "and an array of names was provided" do
- before do
- @applier = @class.new(:sign, %w{host1 host2})
- end
-
- it "should sign the specified waiting certificate requests" do
- @ca.expects(:sign).with("host1")
- @ca.expects(:sign).with("host2")
-
- @applier.apply(@ca)
- end
- end
-
- describe "and :all was provided" do
- it "should sign all waiting certificate requests" do
- @ca.stubs(:waiting?).returns(%w{cert1 cert2})
-
- @ca.expects(:sign).with("cert1")
- @ca.expects(:sign).with("cert2")
-
- @applier = @class.new(:sign, :all)
- @applier.apply(@ca)
- end
-
- it "should fail if there are no waiting certificate requests" do
- @ca.stubs(:waiting?).returns([])
-
- @applier = @class.new(:sign, :all)
- lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
- end
- end
- end
-
- describe ":list" do
- describe "and an empty array was provided" do
- it "should print a string containing all certificate requests" do
- @ca.expects(:waiting?).returns %w{host1 host2}
-
- @applier = @class.new(:list, [])
-
- @applier.expects(:puts).with "host1\nhost2"
-
- @applier.apply(@ca)
- end
- end
-
- describe "and :all was provided" do
- it "should print a string containing all certificate requests and certificates" do
- @ca.expects(:waiting?).returns %w{host1 host2}
- @ca.expects(:list).returns %w{host3 host4}
-
- @applier = @class.new(:list, :all)
-
- @applier.expects(:puts).with "host1"
- @applier.expects(:puts).with "host2"
- @applier.expects(:puts).with "+ host3"
- @applier.expects(:puts).with "+ host4"
-
- @applier.apply(@ca)
- end
- end
-
- describe "and an array of names was provided" do
- it "should print a string of all named hosts that have a waiting request" do
- @ca.expects(:waiting?).returns %w{host1 host2}
- @ca.expects(:list).returns %w{host3 host4}
-
- @applier = @class.new(:list, %w{host1 host2 host3 host4})
-
- @applier.expects(:puts).with "host1"
- @applier.expects(:puts).with "host2"
- @applier.expects(:puts).with "+ host3"
- @applier.expects(:puts).with "+ host4"
-
- @applier.apply(@ca)
- end
- end
- end
-
- describe ":print" do
- describe "and :all was provided" do
- it "should print all certificates" do
- @ca.expects(:list).returns %w{host1 host2}
-
- @applier = @class.new(:print, :all)
-
- @ca.expects(:print).with("host1").returns "h1"
- @applier.expects(:puts).with "h1"
-
- @ca.expects(:print).with("host2").returns "h2"
- @applier.expects(:puts).with "h2"
-
- @applier.apply(@ca)
- end
- end
-
- describe "and an array of names was provided" do
- it "should print each named certificate if found" do
- @applier = @class.new(:print, %w{host1 host2})
-
- @ca.expects(:print).with("host1").returns "h1"
- @applier.expects(:puts).with "h1"
-
- @ca.expects(:print).with("host2").returns "h2"
- @applier.expects(:puts).with "h2"
-
- @applier.apply(@ca)
- end
-
- it "should log any named but not found certificates" do
- @applier = @class.new(:print, %w{host1 host2})
-
- @ca.expects(:print).with("host1").returns "h1"
- @applier.expects(:puts).with "h1"
-
- @ca.expects(:print).with("host2").returns nil
- Puppet.expects(:err).with { |msg| msg.include?("host2") }
-
- @applier.apply(@ca)
- end
- end
- end
+ it "should sign all CSRs whose hostname matches the autosign configuration"
end
end
diff --git a/spec/unit/ssl/certificate_authority/interface.rb b/spec/unit/ssl/certificate_authority/interface.rb
new file mode 100755
index 000000000..617cfa6ba
--- /dev/null
+++ b/spec/unit/ssl/certificate_authority/interface.rb
@@ -0,0 +1,265 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/ssl/certificate_authority'
+
+describe "a normal interface method", :shared => true do
+ it "should call the method on the CA for each host specified if an array was provided" do
+ @ca.expects(@method).with("host1")
+ @ca.expects(@method).with("host2")
+
+ @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, %w{host1 host2})
+
+ @applier.apply(@ca)
+ end
+
+ it "should call the method on the CA for all existing certificates if :all was provided" do
+ @ca.expects(:list).returns %w{host1 host2}
+
+ @ca.expects(@method).with("host1")
+ @ca.expects(@method).with("host2")
+
+ @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :all)
+
+ @applier.apply(@ca)
+ end
+end
+
+describe Puppet::SSL::CertificateAuthority::Interface do
+ before do
+ @class = Puppet::SSL::CertificateAuthority::Interface
+ end
+ describe "when initializing" do
+ it "should set its method using its settor" do
+ @class.any_instance.expects(:method=).with(:generate)
+ @class.new(:generate, :all)
+ end
+
+ it "should set its subjects using the settor" do
+ @class.any_instance.expects(:subjects=).with(:all)
+ @class.new(:generate, :all)
+ end
+ end
+
+ describe "when setting the method" do
+ it "should set the method" do
+ @class.new(:generate, :all).method.should == :generate
+ end
+
+ it "should fail if the method isn't a member of the INTERFACE_METHODS array" do
+ Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false
+
+ lambda { @class.new(:thing, :all) }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe "when setting the subjects" do
+ it "should set the subjects" do
+ @class.new(:generate, :all).subjects.should == :all
+ end
+
+ it "should fail if the subjects setting isn't :all or an array" do
+ lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError)
+ end
+ end
+
+ it "should have a method for triggering the application" do
+ @class.new(:generate, :all).should respond_to(:apply)
+ end
+
+ describe "when applying" do
+ before do
+ # We use a real object here, because :verify can't be stubbed, apparently.
+ @ca = Object.new
+ end
+
+ it "should raise InterfaceErrors" do
+ @applier = @class.new(:revoke, :all)
+
+ @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
+
+ lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
+ end
+
+ it "should log non-Interface failures rather than failing" do
+ @applier = @class.new(:revoke, :all)
+
+ @ca.expects(:list).raises ArgumentError
+
+ Puppet.expects(:err)
+
+ lambda { @applier.apply(@ca) }.should_not raise_error
+ end
+
+ describe "with an empty array specified and the method is not list" do
+ it "should fail" do
+ @applier = @class.new(:sign, [])
+ lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
+ end
+ end
+
+ describe ":generate" do
+ it "should fail if :all was specified" do
+ @applier = @class.new(:generate, :all)
+ lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
+ end
+
+ it "should call :generate on the CA for each host specified" do
+ @applier = @class.new(:generate, %w{host1 host2})
+
+ @ca.expects(:generate).with("host1")
+ @ca.expects(:generate).with("host2")
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe ":verify" do
+ before { @method = :verify }
+ #it_should_behave_like "a normal interface method"
+
+ it "should call the method on the CA for each host specified if an array was provided" do
+ # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
+ end
+
+ it "should call the method on the CA for all existing certificates if :all was provided" do
+ # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
+ end
+ end
+
+ describe ":destroy" do
+ before { @method = :destroy }
+ it_should_behave_like "a normal interface method"
+ end
+
+ describe ":revoke" do
+ before { @method = :revoke }
+ it_should_behave_like "a normal interface method"
+ end
+
+ describe ":sign" do
+ describe "and an array of names was provided" do
+ before do
+ @applier = @class.new(:sign, %w{host1 host2})
+ end
+
+ it "should sign the specified waiting certificate requests" do
+ @ca.expects(:sign).with("host1")
+ @ca.expects(:sign).with("host2")
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and :all was provided" do
+ it "should sign all waiting certificate requests" do
+ @ca.stubs(:waiting?).returns(%w{cert1 cert2})
+
+ @ca.expects(:sign).with("cert1")
+ @ca.expects(:sign).with("cert2")
+
+ @applier = @class.new(:sign, :all)
+ @applier.apply(@ca)
+ end
+
+ it "should fail if there are no waiting certificate requests" do
+ @ca.stubs(:waiting?).returns([])
+
+ @applier = @class.new(:sign, :all)
+ lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
+ end
+ end
+ end
+
+ describe ":list" do
+ describe "and an empty array was provided" do
+ it "should print a string containing all certificate requests" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+
+ @applier = @class.new(:list, [])
+
+ @applier.expects(:puts).with "host1\nhost2"
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and :all was provided" do
+ it "should print a string containing all certificate requests and certificates" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.expects(:list).returns %w{host3 host4}
+
+ @applier = @class.new(:list, :all)
+
+ @applier.expects(:puts).with "host1"
+ @applier.expects(:puts).with "host2"
+ @applier.expects(:puts).with "+ host3"
+ @applier.expects(:puts).with "+ host4"
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and an array of names was provided" do
+ it "should print a string of all named hosts that have a waiting request" do
+ @ca.expects(:waiting?).returns %w{host1 host2}
+ @ca.expects(:list).returns %w{host3 host4}
+
+ @applier = @class.new(:list, %w{host1 host2 host3 host4})
+
+ @applier.expects(:puts).with "host1"
+ @applier.expects(:puts).with "host2"
+ @applier.expects(:puts).with "+ host3"
+ @applier.expects(:puts).with "+ host4"
+
+ @applier.apply(@ca)
+ end
+ end
+ end
+
+ describe ":print" do
+ describe "and :all was provided" do
+ it "should print all certificates" do
+ @ca.expects(:list).returns %w{host1 host2}
+
+ @applier = @class.new(:print, :all)
+
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
+
+ @ca.expects(:print).with("host2").returns "h2"
+ @applier.expects(:puts).with "h2"
+
+ @applier.apply(@ca)
+ end
+ end
+
+ describe "and an array of names was provided" do
+ it "should print each named certificate if found" do
+ @applier = @class.new(:print, %w{host1 host2})
+
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
+
+ @ca.expects(:print).with("host2").returns "h2"
+ @applier.expects(:puts).with "h2"
+
+ @applier.apply(@ca)
+ end
+
+ it "should log any named but not found certificates" do
+ @applier = @class.new(:print, %w{host1 host2})
+
+ @ca.expects(:print).with("host1").returns "h1"
+ @applier.expects(:puts).with "h1"
+
+ @ca.expects(:print).with("host2").returns nil
+ Puppet.expects(:err).with { |msg| msg.include?("host2") }
+
+ @applier.apply(@ca)
+ end
+ end
+ end
+ end
+end