From e2bd3ece23976240c56dd522f04b5e6f4211828e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 7 Feb 2016 19:53:12 -0400 Subject: propellor spin --- src/Propellor/Property/Apache.hs | 21 ++++++++++++--------- src/Propellor/Property/LetsEncrypt.hs | 24 ++++++++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) (limited to 'src/Propellor') diff --git a/src/Propellor/Property/Apache.hs b/src/Propellor/Property/Apache.hs index 38d47b94..c2c32a3b 100644 --- a/src/Propellor/Property/Apache.hs +++ b/src/Propellor/Property/Apache.hs @@ -179,20 +179,23 @@ httpsVirtualHost' domain docroot letos addedcfg = setup -- Everything else redirects to https , "RewriteRule ^/(.*) https://" ++ domain ++ "/$1 [L,R,NE]" ] - certinstaller _domain certfile privkeyfile chainfile _fullchainfile = + certinstaller :: LetsEncrypt.CertInstaller + certinstaller newcert _domain certfile privkeyfile chainfile _fullchainfile = combineProperties (domain ++ " ssl cert installed") [ File.dirExists (takeDirectory cf) - , File.hasContent cf $ vhost (Port 443) - [ "SSLEngine on" - , "SSLCertificateFile " ++ certfile - , "SSLCertificateKeyFile " ++ privkeyfile - , "SSLCertificateChainFile " ++ chainfile - ] - -- always reload; the cert has changed - , reloaded + , File.hasContent cf sslvhost + `onChange` reloaded + -- always reload when the cert has changed + , check (return newcert :: IO Bool) reloaded ] where cf = sslconffile "letsencrypt" + sslvhost = vhost (Port 443) + [ "SSLEngine on" + , "SSLCertificateFile " ++ certfile + , "SSLCertificateKeyFile " ++ privkeyfile + , "SSLCertificateChainFile " ++ chainfile + ] sslconffile s = "/etc/apache2/sites-available/ssl/" ++ domain ++ "/" ++ s ++ ".conf" vhost (Port p) ls = [ "" diff --git a/src/Propellor/Property/LetsEncrypt.hs b/src/Propellor/Property/LetsEncrypt.hs index 651cffd9..2df290be 100644 --- a/src/Propellor/Property/LetsEncrypt.hs +++ b/src/Propellor/Property/LetsEncrypt.hs @@ -26,11 +26,11 @@ type WebRoot = FilePath -- not modify the web server's configuration in any way; instead the -- `CertInstaller` is used once the client has successfully obtained the -- certificate. --- --- This also handles renewing the certificate, and the `CertInstaller` is --- also run after renewal. For renewel to work well, propellor needs to be --- run periodically (at least a couple times per month). -- +-- This also handles renewing the certificate. +-- For renewel to work well, propellor needs to be +-- run periodically (at least a couple times per month). +-- -- See `Propellor.Property.Apache.httpsVirtualHost` for a property built using this. letsEncrypt :: AgreeTOS -> Domain -> WebRoot -> CertInstaller -> Property NoInfo letsEncrypt tos domain = letsEncrypt' tos domain [] @@ -48,9 +48,8 @@ letsEncrypt' (AgreeTOS memail) domain domains webroot certinstaller = if ok then do endstats <- liftIO getstats - if startstats == endstats - then return NoChange - else ensureProperty certsinstalled + ensureProperty $ + certsinstalled (startstats /= endstats) else do liftIO $ hPutStr stderr transcript return FailedChange @@ -80,8 +79,9 @@ letsEncrypt' (AgreeTOS memail) domain domains webroot certinstaller = s <- getFileStatus f return (fileID s, deviceID s, fileMode s, fileSize s, modificationTime s) - certsinstalled = propertyList ("certs installed") $ - flip map alldomains $ \d -> certinstaller d + certsinstalled newcert = propertyList ("certs installed") $ + flip map alldomains $ \d -> certinstaller + newcert d (certFile d) (privKeyFile d) (chainFile d) @@ -91,7 +91,11 @@ letsEncrypt' (AgreeTOS memail) domain domains webroot certinstaller = -- -- For example, it could configure the web server to use the certificate -- files, and restart the web server. -type CertInstaller = Domain -> CertFile -> PrivKeyFile -> ChainFile -> FullChainFile -> Property NoInfo +-- +-- The Bool is True when a new cerficate was just obtained. +-- But, this is also run when the certificate has not changed, so that +-- any changes to the property will take effect. +type CertInstaller = Bool -> Domain -> CertFile -> PrivKeyFile -> ChainFile -> FullChainFile -> Property NoInfo -- | Locations of certificate files generated by lets encrypt. type CertFile = FilePath -- cgit v1.2.3