Class: Puppet::SSL::CertificateAuthority::Interface

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/ssl/certificate_authority/interface.rb

Overview

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.

API:

  • public

Defined Under Namespace

Classes: InterfaceError

Constant Summary collapse

INTERFACE_METHODS =

API:

  • public

[:destroy, :list, :revoke, :generate, :sign, :print, :verify, :fingerprint, :reinventory]
SUBJECTLESS_METHODS =

API:

  • public

[:list, :reinventory]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method, options) ⇒ Interface

Returns a new instance of Interface.

API:

  • public



39
40
41
42
43
44
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 39

def initialize(method, options)
  self.method = method
  self.subjects = options.delete(:to)
  @digest = options.delete(:digest)
  @options = options
end

Instance Attribute Details

#digestObject (readonly)

API:

  • public



13
14
15
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 13

def digest
  @digest
end

#methodObject

API:

  • public



13
14
15
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 13

def method
  @method
end

#optionsObject (readonly)

API:

  • public



13
14
15
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 13

def options
  @options
end

#subjectsObject

API:

  • public



13
14
15
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 13

def subjects
  @subjects
end

Instance Method Details

#apply(ca) ⇒ Object

Actually perform the work.

API:

  • public



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 16

def apply(ca)
  unless subjects || SUBJECTLESS_METHODS.include?(method)
    raise ArgumentError, "You must provide hosts or --all when using #{method}"
  end

  # if the interface implements the method, use it instead of the ca's method
  if respond_to?(method)
    send(method, ca)
  else
    (subjects == :all ? ca.list : subjects).each do |host|
      ca.send(method, host)
    end
  end
end

#fingerprint(ca) ⇒ Object

Print certificate information.

API:

  • public



143
144
145
146
147
148
149
150
151
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 143

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) ⇒ Object

API:

  • public



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 100

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) ⇒ Object

Raises:

API:

  • public



31
32
33
34
35
36
37
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 31

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) ⇒ Object

List the hosts.

API:

  • public



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 47

def list(ca)
  signed = ca.list if [:signed, :all].include?(subjects)
  requests = ca.waiting?

  case subjects
  when :all
    hosts = [signed, requests].flatten
  when :signed
    hosts = signed.flatten
  when nil
    hosts = requests
  else
    hosts = subjects
    signed = ca.list(hosts)
  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
      certs[:invalid][host] = [ Puppet::SSL::Certificate.indirection.find(host), verify_error ]
    elsif (signed and signed.include?(host))
      certs[:signed][host]  = Puppet::SSL::Certificate.indirection.find(host)
    else
      certs[:request][host] = Puppet::SSL::CertificateRequest.indirection.find(host)
    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

Print certificate information.

API:

  • public



132
133
134
135
136
137
138
139
140
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 132

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

#reinventory(ca) ⇒ Object

API:

  • public



162
163
164
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 162

def reinventory(ca)
  ca.inventory.rebuild
end

#sign(ca) ⇒ Object

Signs given certificates or waiting of subjects == :all

Raises:

API:

  • public



154
155
156
157
158
159
160
# File 'lib/puppet/ssl/certificate_authority/interface.rb', line 154

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