3
Puppet::Face.define(:ca, '0.1.0') do
4
copyright "Puppet Labs", 2011
5
license "Apache 2 license; see COPYING"
7
summary "Local Puppet Certificate Authority management."
10
This provides local management of the Puppet Certificate Authority.
12
You can use this subcommand to sign outstanding certificate requests, list
13
and manage local certificates, and inspect the state of the CA.
17
summary "List certificates and/or certificate requests."
20
This will list the current certificates and certificate signing requests
21
in the Puppet CA. You will also get the fingerprint, and any certificate
22
verification failure reported.
25
option "--[no-]all" do
26
summary "Include all certificates and requests."
29
option "--[no-]pending" do
30
summary "Include pending certificate signing requests."
33
option "--[no-]signed" do
34
summary "Include signed certificates."
37
option "--subject PATTERN" do
38
summary "Only list if the subject matches PATTERN."
41
Only include certificates or requests where subject matches PATTERN.
43
PATTERN is interpreted as a regular expression, allowing complex
44
filtering of the content.
48
when_invoked do |options|
49
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
50
unless ca = Puppet::SSL::CertificateAuthority.instance
51
raise "Unable to fetch the CA"
54
pattern = options[:subject].nil? ? nil :
55
Regexp.new(options[:subject], Regexp::IGNORECASE)
57
pending = options[:pending].nil? ? options[:all] : options[:pending]
58
signed = options[:signed].nil? ? options[:all] : options[:signed]
60
# By default we list pending, so if nothing at all was requested...
61
unless pending or signed then pending = true end
65
pending and hosts += ca.waiting?
66
signed and hosts += ca.list
68
pattern and hosts = hosts.select {|hostname| pattern.match hostname }
70
hosts.sort.map {|host| Puppet::SSL::Host.new(host) }
73
when_rendering :console do |hosts|
74
unless ca = Puppet::SSL::CertificateAuthority.instance
75
raise "Unable to fetch the CA"
78
length = hosts.map{|x| x.name.length }.max + 1
81
name = host.name.ljust(length)
82
if host.certificate_request then
83
" #{name} (#{host.certificate_request.fingerprint})"
86
ca.verify(host.certificate)
87
"+ #{name} (#{host.certificate.fingerprint})"
88
rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => e
89
"- #{name} (#{host.certificate.fingerprint}) (#{e.to_s})"
97
when_invoked do |host, options|
98
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
99
unless ca = Puppet::SSL::CertificateAuthority.instance
100
raise "Unable to fetch the CA"
108
when_invoked do |host, options|
109
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
110
unless ca = Puppet::SSL::CertificateAuthority.instance
111
raise "Unable to fetch the CA"
116
rescue ArgumentError => e
117
# This is a bit naff, but it makes the behaviour consistent with the
118
# destroy action. The underlying tools could be nicer for that sort
119
# of thing; they have fairly inconsistent reporting of failures.
120
raise unless e.to_s =~ /Could not find a serial number for /
121
"Nothing was revoked"
127
option "--dns-alt-names NAMES" do
128
summary "Additional DNS names to add to the certificate request"
129
description Puppet.settings.setting(:dns_alt_names).desc
132
when_invoked do |host, options|
133
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
134
unless ca = Puppet::SSL::CertificateAuthority.instance
135
raise "Unable to fetch the CA"
139
ca.generate(host, :dns_alt_names => options[:dns_alt_names])
140
rescue RuntimeError => e
141
if e.to_s =~ /already has a requested certificate/
142
"#{host} already has a certificate request; use sign instead"
146
rescue ArgumentError => e
147
if e.to_s =~ /A Certificate already exists for /
148
"#{host} already has a certificate"
157
option("--[no-]allow-dns-alt-names") do
158
summary "Whether or not to accept DNS alt names in the certificate request"
161
when_invoked do |host, options|
162
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
163
unless ca = Puppet::SSL::CertificateAuthority.instance
164
raise "Unable to fetch the CA"
168
ca.sign(host, options[:allow_dns_alt_names])
169
rescue ArgumentError => e
170
if e.to_s =~ /Could not find certificate request/
180
when_invoked do |host, options|
181
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
182
unless ca = Puppet::SSL::CertificateAuthority.instance
183
raise "Unable to fetch the CA"
190
action :fingerprint do
191
option "--digest ALGORITHM" do
192
summary "The hash algorithm to use when displaying the fingerprint"
195
when_invoked do |host, options|
196
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
197
unless ca = Puppet::SSL::CertificateAuthority.instance
198
raise "Unable to fetch the CA"
202
# I want the default from the CA, not to duplicate it, but passing
203
# 'nil' explicitly means that we don't get that. This works...
204
if options.has_key? :digest
205
ca.fingerprint host, options[:digest]
209
rescue ArgumentError => e
210
raise unless e.to_s =~ /Could not find a certificate or csr for/
217
when_invoked do |host, options|
218
raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
219
unless ca = Puppet::SSL::CertificateAuthority.instance
220
raise "Unable to fetch the CA"
225
{ :host => host, :valid => true }
226
rescue ArgumentError => e
227
raise unless e.to_s =~ /Could not find a certificate for/
228
{ :host => host, :valid => false, :error => e.to_s }
229
rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => e
230
{ :host => host, :valid => false, :error => e.to_s }
234
when_rendering :console do |value|
238
"Could not verify #{value[:host]}: #{value[:error]}"