tools/sanitize-config
pkglib_python_scripts = \
- daemons/import-export
+ daemons/import-export \
+ tools/check-cert-expired
pkglib_SCRIPTS = \
daemons/daemon-util \
dist_TESTS = \
test/daemon-util_unittest.bash \
test/import-export_unittest.bash \
+ test/check-cert-expired_unittest.bash \
$(python_tests)
nodist_TESTS =
xargs -r0 rm -vf
}
+cleanup_node() {
+ # Return if directory for crypto keys doesn't exist
+ [[ -d $CRYPTO_DIR ]] || return 0
+
+ find $CRYPTO_DIR -mindepth 1 -maxdepth 1 -type d | \
+ while read dir; do
+ if $CHECK_CERT_EXPIRED $dir/cert; then
+ rm -vf $dir/{cert,key}
+ rmdir -v --ignore-fail-on-non-empty $dir
+ fi
+ done
+}
+
DATA_DIR=@LOCALSTATEDIR@/lib/ganeti
CLEANER_LOG_DIR=@LOCALSTATEDIR@/log/ganeti/cleaner
QUEUE_ARCHIVE_DIR=$DATA_DIR/queue/archive
+CRYPTO_DIR=@LOCALSTATEDIR@/run/ganeti/crypto
+CHECK_CERT_EXPIRED=@PKGLIBDIR@/check-cert-expired
# Define how many days archived jobs should be left alone
REMOVE_AFTER=21
xargs -r rm -vf
cleanup_master
+cleanup_node
exit 0
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!-- Please adjust the date whenever revising the manpage. -->
- <!ENTITY dhdate "<date>February 11, 2009</date>">
+ <!ENTITY dhdate "<date>May 17, 2010</date>">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1). -->
<!ENTITY dhsection "<manvolnum>8</manvolnum>">
<refentryinfo>
<copyright>
<year>2009</year>
+ <year>2010</year>
<holder>Google Inc.</holder>
</copyright>
&dhdate;
<para>
The <command>&dhpackage;</command> is a periodically run script to clean
- old job files from the job queue archive.
+ old job files from the job queue archive and to remove expired X509
+ certificates and keys.
</para>
<para>
<command>&dhpackage;</command> automatically removes all files older than
21 days from
- <filename>@LOCALSTATEDIR@/lib/ganeti/queue/archive</filename>.
+ <filename>@LOCALSTATEDIR@/lib/ganeti/queue/archive</filename> and all
+ expired certificates and keys from
+ <filename>@LOCALSTATEDIR@/run/ganeti/crypto</filename>
</para>
</refsect1>
--- /dev/null
+#!/bin/bash
+#
+
+# Copyright (C) 2010 Google Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+set -e
+set -o pipefail
+
+export PYTHON=${PYTHON:=python}
+
+CCE=tools/check-cert-expired
+
+err() {
+ echo "$@"
+ echo 'Aborting'
+ exit 1
+}
+
+impexpd_helper() {
+ $PYTHON "${TOP_SRCDIR:-.}/test/import-export_unittest-helper" "$@"
+}
+
+$CCE 2>/dev/null && err 'Accepted empty argument list'
+$CCE foo bar 2>/dev/null && err 'Accepted more than one argument'
+$CCE foo bar baz 2>/dev/null && err 'Accepted more than one argument'
+
+tmpdir=$(mktemp -d)
+trap "rm -rf $tmpdir" EXIT
+
+[[ -f "$tmpdir/cert-not" ]] && err 'File existed when it should not'
+$CCE $tmpdir/cert-not 2>/dev/null && err 'Accepted non-existent file'
+
+VALIDITY=1 impexpd_helper $tmpdir/cert-valid gencert
+$CCE $tmpdir/cert-valid 2>/dev/null && \
+ err 'Reported valid certificate as expired'
+
+VALIDITY=-50 impexpd_helper $tmpdir/cert-expired gencert
+$CCE $tmpdir/cert-expired 2>/dev/null || \
+ err 'Reported expired certificate as valid'
+
+echo > $tmpdir/cert-invalid
+$CCE $tmpdir/cert-invalid 2>/dev/null && \
+ err 'Reported invalid certificate as expired'
+
+echo 'Hello World' > $tmpdir/cert-invalid2
+$CCE $tmpdir/cert-invalid2 2>/dev/null && \
+ err 'Reported invalid certificate as expired'
+
+exit 0
RETRY_INTERVAL = 0.1
TIMEOUT = int(os.getenv("TIMEOUT", 10))
+VALIDITY = int(os.getenv("VALIDITY", 1))
def _GetImportExportData(filename):
elif what == "connected":
WaitForConnected(filename)
elif what == "gencert":
- utils.GenerateSelfSignedSslCert(filename, validity=1)
+ utils.GenerateSelfSignedSslCert(filename, validity=VALIDITY)
else:
raise Exception("Unknown command '%s'" % what)
--- /dev/null
+#!/usr/bin/python
+#
+
+# Copyright (C) 2010 Google Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+"""Tool to detect expired X509 certificates.
+
+"""
+
+# pylint: disable-msg=C0103
+# C0103: Invalid name check-cert-expired
+
+import os.path
+import sys
+import OpenSSL
+
+from ganeti import constants
+from ganeti import cli
+from ganeti import utils
+
+
+def main():
+ """Main routine.
+
+ """
+ program = os.path.basename(sys.argv[0])
+
+ if len(sys.argv) != 2:
+ cli.ToStderr("Usage: %s <certificate-path>", program)
+ sys.exit(constants.EXIT_FAILURE)
+
+ filename = sys.argv[1]
+
+ # Read certificate
+ try:
+ cert_pem = utils.ReadFile(filename)
+ except EnvironmentError, err:
+ cli.ToStderr("Unable to read %s: %s", filename, err)
+ sys.exit(constants.EXIT_FAILURE)
+
+ # Check validity
+ try:
+ cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
+ cert_pem)
+
+ (errcode, msg) = utils.VerifyX509Certificate(cert, None, None)
+ if msg:
+ cli.ToStderr("%s: %s", filename, msg)
+ if errcode == utils.CERT_ERROR:
+ sys.exit(constants.EXIT_SUCCESS)
+
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except Exception, err: # pylint: disable-msg=W0703
+ cli.ToStderr("Unable to check %s: %s", filename, err)
+
+ sys.exit(constants.EXIT_FAILURE)
+
+
+if __name__ == "__main__":
+ main()