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

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

Defined Under Namespace

Classes: InterfaceError

Constant Summary collapse

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method, options) ⇒ Interface

Returns a new instance of Interface.



43
44
45
46
47
48
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 43

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

Instance Attribute Details

#digestObject (readonly)

Returns the value of attribute digest.



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

def digest
  @digest
end

#methodObject

Returns the value of attribute method.



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

def method
  @method
end

#optionsObject (readonly)

Returns the value of attribute options.



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

def options
  @options
end

#subjectsObject

Returns the value of attribute subjects.



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

def subjects
  @subjects
end

Instance Method Details

#apply(ca) ⇒ Object

Actually perform the work.



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

def apply(ca)
  unless subjects or method == :list
    raise ArgumentError, "You must provide hosts or :all when using #{method}"
  end

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

    (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 #{method}: #{detail}"
    raise
  end
end

#fingerprint(ca) ⇒ Object

Print certificate information.



149
150
151
152
153
154
155
156
157
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 149

def fingerprint(ca)
  (subjects == :all ? ca.list + ca.waiting?: subjects).each do |host|
    if value = ca.fingerprint(host, @digest)
      puts "#{host} #{value}"
    else
      Puppet.err "Could not find certificate for #{host}"
    end
  end
end

#format_host(ca, host, type, info, width) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 106

def format_host(ca, host, type, info, width)
  certish, verify_error = info
  alt_names = case type
              when :signed
                certish.subject_alt_names
              when :request
                certish.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 = "(#{ca.fingerprint(host, @digest)})"

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

  [glyph, name, fingerprint, alt_str, explanation].compact.join(' ')
end

#generate(ca) ⇒ Object

Raises:



35
36
37
38
39
40
41
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 35

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.



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
99
100
101
102
103
104
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 51

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

Print certificate information.



138
139
140
141
142
143
144
145
146
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 138

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

Sign a given certificate.

Raises:



160
161
162
163
164
165
166
# File 'lib/vendor/puppet/ssl/certificate_authority/interface.rb', line 160

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