~mathiaz/puppet/reductivelabs-master

« back to all changes in this revision

Viewing changes to bin/puppetca

  • Committer: Luke Kanies
  • Date: 2008-04-20 00:08:36 UTC
  • Revision ID: git-v1:ebdbe4880d8c20965ac21a473b2bfc1ab953b6d4
Added an Interface class to the CA to model puppetca's usage.

This class provides all of the semantics from puppetca,
and appears to entirely duplicate the behaviour of the existing
executable, with basically all of the code in a library
file, instead of the executable.

As such, I've deleted the test for the executable.  We should have
one, but it's not nearly as important.

Show diffs side-by-side

added added

removed removed

Lines of Context:
95
95
# Licensed under the GNU Public License
96
96
 
97
97
require 'puppet'
98
 
require 'puppet/sslcertificates'
 
98
require 'puppet/ssl/certificate_authority'
99
99
require 'getoptlong'
100
100
 
101
101
options = [
118
118
 
119
119
result = GetoptLong.new(*options)
120
120
 
 
121
modes = Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS
 
122
 
 
123
all = false
121
124
mode = nil
122
 
all = false
123
 
generate = nil
124
 
 
125
 
modes = [:clean, :list, :revoke, :generate, :sign, :print, :verify]
126
125
 
127
126
begin
128
127
    result.each { |opt,arg|
129
128
        case opt
 
129
            when "--clean"
 
130
                mode = :destroy
130
131
            when "--all"
131
132
                all = true
132
133
            when "--debug"
133
134
                Puppet::Util::Log.level = :debug
134
 
            when "--generate"
135
 
                generate = arg
136
 
                mode = :generate
137
135
            when "--help"
138
136
                if Puppet.features.usage?
139
137
                    RDoc::usage && exit
141
139
                    puts "No help available unless you have RDoc::usage installed"
142
140
                    exit
143
141
                end
144
 
            when "--list"
145
 
                mode = :list
146
 
            when "--revoke"
147
 
                mode = :revoke
148
 
            when "--sign"
149
 
                mode = :sign
150
142
            when "--version"
151
143
                puts "%s" % Puppet.version
152
144
                exit
172
164
Puppet.genconfig
173
165
Puppet.genmanifest
174
166
 
 
167
Puppet::Util::Log.newdestination :console
 
168
 
175
169
begin
176
 
    ca = Puppet::SSLCertificates::CA.new()
 
170
    ca = Puppet::SSL::CertificateAuthority.new
177
171
rescue => detail
178
 
    if Puppet[:debug]
179
 
        puts detail.backtrace
180
 
    end
 
172
    puts detail.backtrace if Puppet[:trace]
181
173
    puts detail.to_s
182
174
    exit(23)
183
175
end
187
179
    exit(12)
188
180
end
189
181
 
190
 
if [:verify, :print, :generate, :clean, :revoke, :list].include?(mode)
 
182
if all
 
183
    hosts = :all
 
184
else
191
185
    hosts = ARGV.collect { |h| h.downcase }
192
186
end
193
187
 
194
 
if [:sign, :list].include?(mode)
195
 
    waiting = ca.list
196
 
    unless waiting.length > 0 or (mode == :list and all)
197
 
        puts "No certificates to sign"
198
 
        if ARGV.length > 0
199
 
            exit(17)
200
 
        else
201
 
            exit(0)
202
 
        end
203
 
    end
204
 
end
205
 
 
206
 
case mode
207
 
when :list
208
 
    waiting = ca.list
209
 
    if waiting.length > 0
210
 
        puts waiting.join("\n")
211
 
    end
212
 
    if all
213
 
        puts ca.list_signed.collect { |cert | cert.sub(/^/,"+ ") }.join("\n")
214
 
    end
215
 
when :clean
216
 
    if hosts.empty?
217
 
        $stderr.puts "You must specify one or more hosts to clean"
218
 
        exit(24)
219
 
    end
220
 
    cleaned = false
221
 
    hosts.each do |host|
222
 
        cert = ca.getclientcert(host)[0]
223
 
        if cert.nil?
224
 
            $stderr.puts "Could not find client certificate for %s" % host
225
 
            next
226
 
        end
227
 
        ca.clean(host)
228
 
        cleaned = true
229
 
    end
230
 
    unless cleaned
231
 
        exit(27)
232
 
    end
233
 
when :sign
234
 
    to_sign = ARGV.collect { |h| h.downcase }
235
 
    unless to_sign.length > 0 or all
236
 
        $stderr.puts(
237
 
            "You must specify to sign all certificates or you must specify hostnames"
238
 
        )
239
 
        exit(24)
240
 
    end
241
 
 
242
 
    unless all
243
 
        to_sign.each { |host|
244
 
            unless waiting.include?(host)
245
 
                $stderr.puts "No waiting request for %s" % host
246
 
            end
247
 
        }
248
 
        waiting = waiting.find_all { |host|
249
 
            to_sign.include?(host)
250
 
        }
251
 
    end
252
 
 
253
 
    waiting.each { |host|
254
 
        begin
255
 
            csr = ca.getclientcsr(host)
256
 
        rescue => detail
257
 
            $stderr.puts "Could not retrieve request for %s: %s" % [host, detail]
258
 
        end
259
 
 
260
 
        begin
261
 
            ca.sign(csr)
262
 
            $stderr.puts "Signed %s" % host
263
 
        rescue => detail
264
 
            $stderr.puts "Could not sign request for %s: %s" % [host, detail]
265
 
        end
266
 
 
267
 
        begin
268
 
            ca.removeclientcsr(host)
269
 
        rescue => detail
270
 
            $stderr.puts "Could not remove request for %s: %s" % [host, detail]
271
 
        end
272
 
    }
273
 
when :generate
274
 
    # we need to generate a certificate for a host
275
 
    hosts.each { |host|
276
 
        puts "Generating certificate for %s" % host
277
 
        cert = Puppet::SSLCertificates::Certificate.new(
278
 
            :name => host
279
 
        )
280
 
        cert.mkcsr
281
 
        signedcert, cacert = ca.sign(cert.csr)
282
 
 
283
 
        cert.cert = signedcert
284
 
        cert.cacert = cacert
285
 
        cert.write
286
 
    }
287
 
when :print
288
 
    hosts.each { |h|
289
 
        cert = ca.getclientcert(h)[0]
290
 
        puts cert.to_text
291
 
    }
292
 
when :revoke
293
 
    hosts.each { |h|
294
 
        serial = nil
295
 
        if h =~ /^0x[0-9a-f]+$/
296
 
            serial = h.to_i(16)
297
 
        elsif h =~ /^[0-9]+$/
298
 
            serial = h.to_i
299
 
        else
300
 
            cert = ca.getclientcert(h)[0]
301
 
            if cert.nil?
302
 
                $stderr.puts "Could not find client certificate for %s" % h
303
 
            else
304
 
                serial = cert.serial
305
 
            end
306
 
        end
307
 
        unless serial.nil?
308
 
            ca.revoke(serial)
309
 
            puts "Revoked certificate with serial #{serial}"
310
 
        end
311
 
    }
312
 
when :verify
313
 
    unless ssl = %x{which openssl}.chomp
314
 
        raise "Can't verify certificates without the openssl binary and could not find one"
315
 
    end
316
 
    success = true
317
 
 
318
 
    cacert = Puppet[:localcacert]
319
 
 
320
 
    hosts.each do |host|
321
 
        print "%s: " % host
322
 
        file = ca.host2certfile(host)
323
 
        unless FileTest.exist?(file)
324
 
            puts "no certificate found"
325
 
            success = false
326
 
            next
327
 
        end
328
 
 
329
 
 
330
 
        command = %{#{ssl} verify -CAfile #{cacert} #{file}}
331
 
        output = %x{#{command}}
332
 
        if $? == 0
333
 
            puts "valid"
334
 
        else
335
 
            puts output
336
 
            success = false
337
 
        end
338
 
    end
339
 
else
340
 
    $stderr.puts "Invalid mode %s" % mode
341
 
    exit(42)
342
 
end
343
 
 
 
188
begin
 
189
    ca.apply(mode, :to => hosts)
 
190
rescue => detail
 
191
    puts detail.backtrace if Puppet[:trace]
 
192
    puts detail.to_s
 
193
    exit(24)
 
194
end