class CertificateAuthority::CertificateAuthority::Interface

This class is basically a hidden class that knows how to act on the CA. Its job is to provide a CLI-like interface to the CA class.

Constants

INTERFACE_METHODS

Attributes

digest[R]
method[R]
options[R]
subjects[R]

Public Class Methods

new(method, options) click to toggle source
# File lib/puppet/ssl/certificate_authority/interface.rb, line 34
def initialize(method, options)
  self.method = method
  self.subjects = options.delete(:to)
  @digest = options.delete(:digest)
  @options = options
end

Public Instance Methods

apply(ca) click to toggle source

Actually perform the work.

# File lib/puppet/ssl/certificate_authority/interface.rb, line 14
def apply(ca)
  unless subjects or method == :list
    raise ArgumentError, "You must provide hosts or --all when using #{method}"
  end

  return send(method, ca) if respond_to?(method)

  (subjects == :all ? ca.list : subjects).each do |host|
    ca.send(method, host)
  end
end
fingerprint(ca) click to toggle source

Print certificate information.

# File lib/puppet/ssl/certificate_authority/interface.rb, line 140
def fingerprint(ca)
  (subjects == :all ? ca.list + ca.waiting?: subjects).each do |host|
    if cert = (Puppet::SSL::Certificate.indirection.find(host) || Puppet::SSL::CertificateRequest.indirection.find(host))
      puts "#{host} #{cert.digest(@digest)}"
    else
      Puppet.err "Could not find certificate for #{host}"
    end
  end
end
format_host(ca, host, type, info, width) click to toggle source
# File lib/puppet/ssl/certificate_authority/interface.rb, line 97
def format_host(ca, host, type, info, width)
  cert, verify_error = info
  alt_names = case type
              when :signed
                cert.subject_alt_names
              when :request
                cert.subject_alt_names
              else
                []
              end

  alt_names.delete(host)

  alt_str = "(alt names: #{alt_names.map(&:inspect).join(', ')})" unless alt_names.empty?

  glyph = {:signed => '+', :request => ' ', :invalid => '-'}[type]

  name = host.inspect.ljust(width)
  fingerprint = cert.digest(@digest).to_s

  explanation = "(#{verify_error})" if verify_error

  [glyph, name, fingerprint, alt_str, explanation].compact.join(' ')
end
generate(ca) click to toggle source
# File lib/puppet/ssl/certificate_authority/interface.rb, line 26
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, options)
  end
end
list(ca) click to toggle source

List the hosts.

# File lib/puppet/ssl/certificate_authority/interface.rb, line 42
def list(ca)
  signed = ca.list
  requests = ca.waiting?

  case subjects
  when :all
    hosts = [signed, requests].flatten
  when :signed
    hosts = signed.flatten
  when nil
    hosts = requests
  else
    hosts = subjects
  end

  certs = {:signed => {}, :invalid => {}, :request => {}}

  return if hosts.empty?

  hosts.uniq.sort.each do |host|
    begin
      ca.verify(host) unless requests.include?(host)
    rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => details
      verify_error = details.to_s
    end

    if verify_error
      cert = Puppet::SSL::Certificate.indirection.find(host)
      certs[:invalid][host] = [cert, verify_error]
    elsif signed.include?(host)
      cert = Puppet::SSL::Certificate.indirection.find(host)
      certs[:signed][host] = cert
    else
      req = Puppet::SSL::CertificateRequest.indirection.find(host)
      certs[:request][host] = req
    end
  end

  names = certs.values.map(&:keys).flatten

  name_width = names.sort_by(&:length).last.length rescue 0
  # We quote these names, so account for those characters
  name_width += 2

  output = [:request, :signed, :invalid].map do |type|
    next if certs[type].empty?

    certs[type].map do |host,info|
      format_host(ca, host, type, info, name_width)
    end
  end.flatten.compact.sort.join("\n")

  puts output
end
method=(method) click to toggle source

Set the method to apply.

# File lib/puppet/ssl/certificate_authority/interface.rb, line 123
def method=(method)
  raise ArgumentError, "Invalid method #{method} to apply" unless INTERFACE_METHODS.include?(method)
  @method = method
end
print(ca) click to toggle source

Print certificate information.

sign(ca) click to toggle source

Sign a given certificate.

# File lib/puppet/ssl/certificate_authority/interface.rb, line 151
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, options[:allow_dns_alt_names])
  end
end
subjects=(value) click to toggle source

Set the list of hosts we’re operating on. Also supports keywords.

# File lib/puppet/ssl/certificate_authority/interface.rb, line 160
def subjects=(value)
  unless value == :all or value == :signed or value.is_a?(Array)
    raise ArgumentError, "Subjects must be an array or :all; not #{value}"
  end

  value = nil if value.is_a?(Array) and value.empty?

  @subjects = value
end