diff options
author | Luke Kanies <luke@madstop.com> | 2008-04-19 19:08:36 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-04-19 19:08:36 -0500 |
commit | ebdbe4880d8c20965ac21a473b2bfc1ab953b6d4 (patch) | |
tree | 3ad90a8ef93313f95db4f2976bd043c4f8fe7640 /lib/puppet | |
parent | 934fbba81cb18f05e07675d79a2e830c4e95c918 (diff) | |
download | puppet-ebdbe4880d8c20965ac21a473b2bfc1ab953b6d4.tar.gz puppet-ebdbe4880d8c20965ac21a473b2bfc1ab953b6d4.tar.xz puppet-ebdbe4880d8c20965ac21a473b2bfc1ab953b6d4.zip |
Added an Interface class to the CA to model puppetca's usage.
This class provides all of the semantics from puppetca,
and appears to entirely duplicate the behaviour of the existing
executable, with basically all of the code in a library
file, instead of the executable.
As such, I've deleted the test for the executable. We should have
one, but it's not nearly as important.
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/ssl/certificate_authority.rb | 121 | ||||
-rw-r--r-- | lib/puppet/ssl/certificate_revocation_list.rb | 1 |
2 files changed, 122 insertions, 0 deletions
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb index 2399c7204..8785ee5b0 100644 --- a/lib/puppet/ssl/certificate_authority.rb +++ b/lib/puppet/ssl/certificate_authority.rb @@ -14,8 +14,129 @@ 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 + attr_reader :name, :host + # Create and run an applicator. I wanted to build an interface where you could do + # something like 'ca.apply(:generate).to(:all) but I don't think it's really possible. + def apply(method, options) + unless options[:to] + raise ArgumentError, "You must specify the hosts to apply to; valid values are an array or the symbol :all" + end + applier = Interface.new(method, options[:to]) + + applier.apply(self) + end + # Retrieve (or create, if necessary) the certificate revocation list. def crl unless defined?(@crl) diff --git a/lib/puppet/ssl/certificate_revocation_list.rb b/lib/puppet/ssl/certificate_revocation_list.rb index ca7b7db65..96b71c7a3 100644 --- a/lib/puppet/ssl/certificate_revocation_list.rb +++ b/lib/puppet/ssl/certificate_revocation_list.rb @@ -30,6 +30,7 @@ class Puppet::SSL::CertificateRevocationList < Puppet::SSL::Base # CA, then write the CRL back to disk. The REASON must be one of the # OpenSSL::OCSP::REVOKED_* reasons def revoke(serial, cakey, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE) + Puppet.notice "Revoked certificate with serial %s" % serial time = Time.now # Add our revocation to the CRL. |