Skip to content
This repository has been archived by the owner on Jul 14, 2022. It is now read-only.

Commit

Permalink
Fix nginx config generation when ssl certs don't yet exist
Browse files Browse the repository at this point in the history
Reviewers: barry

Subscribers: #helix_omniscient

Differential Revision: http://phab.helixta.com.au/D23139
  • Loading branch information
timbod7 committed Mar 29, 2019
1 parent 200d620 commit 69f7b77
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 40 deletions.
4 changes: 2 additions & 2 deletions adl/nginx.adl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ struct NginxHttpEndPoint {
};
struct NginxHttpsEndPoint {
String serverNames;
String sslCertPath;
String sslCertKeyPath;
Nullable<String> sslCertPath;
Nullable<String> sslCertKeyPath;
String letsencryptWwwDir;
Nullable<Word32> port;
};
Expand Down
6 changes: 4 additions & 2 deletions config/nginx.conf.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ http {
listen 443 ssl;
server_name {{serverNames}};
ssl_certificate {{sslCertPath}};
ssl_certificate_key {sslCertKeyPath}};
ssl_certificate_key {{sslCertKeyPath}};
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Expand All @@ -97,13 +97,15 @@ http {
return 503;
}
}
{{#sslCertPath}}
server {
listen 443;
server_name {{serverNames}};
ssl_certificate {{sslCertPath}};
ssl_certificate_key {sslCertKeyPath}};
ssl_certificate_key {{sslCertKeyPath}};
return 503;
}
{{/sslCertPath}}
{{/port}}
{{/https}}
{{/endPoints}}
Expand Down
6 changes: 3 additions & 3 deletions src/ADL/Nginx.hs
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ instance AdlValue NginxHttpEndPoint where

data NginxHttpsEndPoint = NginxHttpsEndPoint
{ nhse_serverNames :: T.Text
, nhse_sslCertPath :: T.Text
, nhse_sslCertKeyPath :: T.Text
, nhse_sslCertPath :: ADL.Core.Nullable.Nullable (T.Text)
, nhse_sslCertKeyPath :: ADL.Core.Nullable.Nullable (T.Text)
, nhse_letsencryptWwwDir :: T.Text
, nhse_port :: ADL.Core.Nullable.Nullable (Data.Word.Word32)
}
deriving (Prelude.Eq,Prelude.Ord,Prelude.Show)

mkNginxHttpsEndPoint :: T.Text -> T.Text -> T.Text -> T.Text -> ADL.Core.Nullable.Nullable (Data.Word.Word32) -> NginxHttpsEndPoint
mkNginxHttpsEndPoint :: T.Text -> ADL.Core.Nullable.Nullable (T.Text) -> ADL.Core.Nullable.Nullable (T.Text) -> T.Text -> ADL.Core.Nullable.Nullable (Data.Word.Word32) -> NginxHttpsEndPoint
mkNginxHttpsEndPoint serverNames sslCertPath sslCertKeyPath letsencryptWwwDir port = NginxHttpsEndPoint serverNames sslCertPath sslCertKeyPath letsencryptWwwDir port

instance AdlValue NginxHttpsEndPoint where
Expand Down
80 changes: 47 additions & 33 deletions src/Commands/ProxyMode/LocalState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -237,46 +237,60 @@ writeNginxConfig tcfg pm path eps = do
let templatePath = T.unpack templatePath0
TM.automaticCompile [takeDirectory templatePath] templatePath

context <- nginxConfigContext tcfg pm eps

case etemplate of
Left err -> error (show err)
Right template -> do
let json = removeNullKeys (adlToJson context)
text = TM.substitute template json
LBS.writeFile (replaceExtension path ".ctx.json") (JS.encode json)
T.writeFile path text
where
-- Build the data context to feed the mustach template
context = NginxConfContext
{ ncc_healthCheck = case (tc_healthCheck tcfg, eps) of
(Just hc,(_,Just deploy):_) -> NL.fromValue (NginxHealthCheck
{ nhc_incomingPath = hc_incomingPath hc
, nhc_outgoingPath = hc_outgoingPath hc
, nhc_outgoingPort = d_port deploy
})
_ -> NL.null
, ncc_endPoints = fmap contextEndPoint eps
}
contextEndPoint (ep@EndPoint{ep_etype=Ep_httpOnly},deploy) = Ne_http
NginxHttpEndPoint
{ nhe_serverNames = T.intercalate " " (ep_serverNames ep)
, nhe_port = NL.fromMaybe (fmap d_port deploy)
}
contextEndPoint (ep@EndPoint{ep_etype=Ep_httpsWithRedirect certMode},deploy) = Ne_https
NginxHttpsEndPoint
{ nhse_serverNames = T.intercalate " " (ep_serverNames ep)
, nhse_port = NL.fromMaybe (fmap d_port deploy)
, nhse_sslCertPath = sslCertPath certMode
, nhse_sslCertKeyPath = sslCertKeyPath certMode
, nhse_letsencryptWwwDir = tc_letsencryptWwwDir tcfg
}

sslCertPath :: SslCertMode -> T.Text
sslCertPath (Scm_explicit scp) = scp_sslCertificate scp
sslCertPath Scm_generated = tc_letsencryptPrefixDir tcfg <> "/etc/letsencrypt/live/" <> (tc_autoCertName tcfg) <> "/fullchain.pem"

sslCertKeyPath :: SslCertMode -> T.Text
sslCertKeyPath (Scm_explicit scp) = scp_sslCertificateKey scp
sslCertKeyPath Scm_generated = tc_letsencryptPrefixDir tcfg <> "/etc/letsencrypt/live/" <> (tc_autoCertName tcfg) <>"/privkey.pem";

-- build up the context to be injected into the nginx config template
nginxConfigContext:: ToolConfig -> ProxyModeConfig -> [(EndPoint,Maybe Deploy)] -> IO NginxConfContext
nginxConfigContext tcfg pm eps = do
-- We only include the ssl paths for the generated certificate in
-- the context if the physical paths exist on disk
genSslCertPath <- existingFilePath (tc_letsencryptPrefixDir tcfg <> "/etc/letsencrypt/live/" <> (tc_autoCertName tcfg) <> "/fullchain.pem")
genSslCertKeyPath <- existingFilePath (tc_letsencryptPrefixDir tcfg <> "/etc/letsencrypt/live/" <> (tc_autoCertName tcfg) <>"/privkey.pem")
let context = NginxConfContext
{ ncc_healthCheck = case (tc_healthCheck tcfg, eps) of
(Just hc,(_,Just deploy):_) -> NL.fromValue (NginxHealthCheck
{ nhc_incomingPath = hc_incomingPath hc
, nhc_outgoingPath = hc_outgoingPath hc
, nhc_outgoingPort = d_port deploy
})
_ -> NL.null
, ncc_endPoints = fmap contextEndPoint eps
}
contextEndPoint (ep@EndPoint{ep_etype=Ep_httpOnly},deploy) = Ne_http
NginxHttpEndPoint
{ nhe_serverNames = T.intercalate " " (ep_serverNames ep)
, nhe_port = NL.fromMaybe (fmap d_port deploy)
}
contextEndPoint (ep@EndPoint{ep_etype=Ep_httpsWithRedirect certMode},deploy) = Ne_https
NginxHttpsEndPoint
{ nhse_serverNames = T.intercalate " " (ep_serverNames ep)
, nhse_port = NL.fromMaybe (fmap d_port deploy)
, nhse_sslCertPath = sslCertPath certMode
, nhse_sslCertKeyPath = sslCertKeyPath certMode
, nhse_letsencryptWwwDir = tc_letsencryptWwwDir tcfg
}
sslCertPath :: SslCertMode -> NL.Nullable T.Text
sslCertPath (Scm_explicit scp) = NL.fromValue (scp_sslCertificate scp)
sslCertPath Scm_generated = genSslCertPath

sslCertKeyPath :: SslCertMode -> NL.Nullable T.Text
sslCertKeyPath (Scm_explicit scp) = NL.fromValue (scp_sslCertificateKey scp)
sslCertKeyPath Scm_generated = genSslCertKeyPath

return context

existingFilePath :: T.Text -> IO (NL.Nullable T.Text)
existingFilePath path = do
exists <- doesFileExist (T.unpack path)
return (if exists then (NL.fromValue path) else NL.null)

-- Extend the release template context with port variables,
-- which include the http port where the deploy will make
Expand Down

0 comments on commit 69f7b77

Please sign in to comment.