# 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.

    # File lib/puppet/ssl/certificate_authority/interface.rb, line 129
    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 #{host}"
        end
      end
    end

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