Commit 3a4e3b33 authored by Patrick J Cherry's avatar Patrick J Cherry
Browse files

common: Added --force flag to symbiosis-ssl to allow certs to be regenerated.

Also fixed up retrying when writing fails.  In now retries, and shouts
louder if the second attempt fails.
parent 98b54c2f
#!/usr/bin/ruby
#
#
# NAME
# symbiosis-ssl - Manage and generate SSL certificates
# symbiosis-ssl - Manage and generate SSL certificates
#
# SYNOPSIS
# symbiosis-ssl [ --threshold N ] [ --no-generate ] [ --no-rollover ] [ --verbose ] [ --manual ]
# [ --help ] [ DOMAIN DOMAIN ...]
#
# OPTIONS
# --force Re-generate certificates even if they're not due to be renewed.
#
# --threshold N Number days before expiry that certificates should be renewed. Defaults to 10.
#
# --no-generate Do not try and generate keys or certificates.
......@@ -36,6 +38,7 @@ opts = GetoptLong.new(
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
[ '--manual', '-m', GetoptLong::NO_ARGUMENT ],
[ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
[ '--force', '-f', GetoptLong::NO_ARGUMENT ],
[ '--threshold', '-t', GetoptLong::REQUIRED_ARGUMENT ],
[ '--no-generate', '-G', GetoptLong::NO_ARGUMENT ],
[ '--no-rollover', '-R', GetoptLong::NO_ARGUMENT ],
......@@ -47,6 +50,7 @@ $VERBOSE = false
prefix = "/srv"
do_generate = do_rollover = true
threshold = 10
force = false
opts.each do |opt,arg|
case opt
......@@ -54,6 +58,8 @@ opts.each do |opt,arg|
do_generate = false
when '--no-rollover'
do_rollover = false
when '--force'
force = true
when '--threshold'
begin
threshold = Integer(arg)
......@@ -106,7 +112,7 @@ ARGV.each do |arg|
domain = Symbiosis::Domains.find(arg.to_s, prefix)
if domain.nil?
warn "** Unable to find/parse domain #{arg.inspect}"
warn "** Unable to find/parse domain #{arg.inspect}"
next
end
......@@ -135,7 +141,7 @@ now = Time.now
domains.each do |domain|
begin
domain.ssl_magic(threshold, do_generate, do_rollover, now)
domain.ssl_magic(threshold, do_generate, do_rollover, force, now)
rescue StandardError => err
puts "\t!! Failed: #{err.to_s.gsub($/,'')}" if $VERBOSE
puts err.backtrace.join("\n") if $DEBUG
......
......@@ -160,9 +160,8 @@ module Symbiosis
# This fetches the certificate from using ssl_provider_class. If
# ssl_provider_class does not return a suitable Class, nil is returned.
#
# Returns an hash of
#
# { :key, :certificate, :request, :bundle}
# Returns the an ssl_provider instance, having requested the certificate
# etc.
#
def ssl_fetch_new_certificate
ssl_provider_class = self.ssl_provider_class
......@@ -372,7 +371,7 @@ module Symbiosis
# * generation
# * rollover
#
def ssl_magic(threshold = 14, do_generate = true, do_rollover = true, now = Time.now)
def ssl_magic(threshold = 14, do_generate = true, do_rollover = true, force = false, now = Time.now)
puts "* Examining certificates for #{self.name}" if $VERBOSE
......@@ -386,18 +385,18 @@ module Symbiosis
if set.is_a?(Symbiosis::SSL::CertificateSet)
expires_in = ((set.certificate.not_after - now)/86400.0).round
if expires_in < 14
if expires_in < threshold
puts "\tThe certificate is due to expire in #{expires_in} days" if $VERBOSE
end
else
puts "\tNo valid certificates found." if $VERBOSE
puts "\tNo valid certificate sets found." if $VERBOSE
end
#
# Stage 1: Generate
#
if do_generate and (set.nil? or (expires_in.is_a?(Integer) and expires_in < threshold))
if do_generate and (set.nil? or (expires_in.is_a?(Integer) and expires_in < threshold) or force)
#
# If ssl-provision has been disabled, move on.
#
......@@ -417,14 +416,20 @@ module Symbiosis
cert_set.name = self.ssl_next_set_name
retried = false
retries = 0
begin
cert_set.write
rescue Errno::ENOTDIR, Errno::EEXIST
cert_set.name = cert_set.name.succ!
rescue Errno::ENOTDIR, Errno::EEXIST => err
cert_set.name = cert_set.name.succ
cert_set.directory = cert_set.name
retried = true
retry unless retried
retries += 1
#
# Retry if we've failed once already.
#
retry if retries <= 1
raise RuntimeError, "Failed to write set (#{err.to_s})"
end
@ssl_available_sets << cert_set
......
......@@ -882,6 +882,12 @@ class SSLTest < Test::Unit::TestCase
assert(File.exist?(current_dir), "The link to current should have been generated.")
assert_equal(expected_dir, File.readlink(current_dir))
#
# And run it again. Nothing should change
#
assert_nothing_raised{ result = @domain.ssl_magic(14) }
assert_equal(expected_dir, File.readlink(current_dir))
#
# Now test rolling over lots of times
#
......@@ -906,6 +912,24 @@ class SSLTest < Test::Unit::TestCase
FileUtils.touch(expected_dir)
assert_nothing_raised{ result = @domain.ssl_magic(500) }
#
# Now test a forced roll-over
#
current_cert = @domain.ssl_certificate
@domain.ssl_magic(14,true,true,false)
#
# Make sure nothing happens with force set to false.
#
assert_equal(current_cert.to_pem, @domain.ssl_certificate.to_pem, "Existing certificate replaced, even with force off")
#
# And do it again, this time set the flag to true. It should regenerate it.
#
@domain.ssl_magic(14,true,true,true)
assert(current_cert.to_pem != @domain.ssl_certificate.to_pem, "Certificate not replaced with force on")
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment