reworked constants into configurable settings

This commit is contained in:
Lucy Cifferello
2020-03-12 17:26:27 -06:00
parent 924f5df8e1
commit 74d3c0c1b8
10 changed files with 97 additions and 92 deletions

View File

@@ -0,0 +1,6 @@
{
"0.1.0": "1.0.0",
"0.1.1": "1.0.0",
"0.1.2": "1.1.0",
"0.1.3": "1.1.0"
}

View File

@@ -28,4 +28,7 @@ ip-from-header: "_env:YESOD_IP_FROM_HEADER:false"
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:YESOD_PGPASS:'123'")
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
app-compatibility-path: "_env:APP_COMPATIBILITY_CONFIG:/etc/start9/registry/compatibility.json"
app-compatibility-path: "_env:APP_COMPATIBILITY_CONFIG:/etc/start9/registry/compatibility.json"
resources-path: "_env:RESOURCES_PATH:/var/www/html/resources"
ssl-path: "_env:SSL_PATH:/var/ssl"
registry-hostname: "_env:REGISTRY_HOSTNAME:registry.start9labs.com"

View File

@@ -165,16 +165,15 @@ startApp :: AgentCtx -> IO ()
startApp foundation = do
-- set up ssl certificates
putStrLn @Text "Setting up SSL"
setupSsl
_ <- setupSsl <$> getAppSettings
putStrLn @Text "SSL Setup Complete"
startWeb foundation
startWeb :: AgentCtx -> IO ()
startWeb foundation = do
app <- makeApplication foundation
putStrLn @Text $ "Launching Web Server on port " <> show (appPort $ appSettings foundation)
let AppSettings{..} = appSettings foundation
putStrLn @Text $ "Launching Web Server on port " <> show appPort
action <- async $ runTLS
(tlsSettings sslCertLocation sslKeyLocation)
(warpSettings foundation)

View File

@@ -1,21 +0,0 @@
module Constants where
import Data.Aeson
import Data.Aeson.Types
import Data.Maybe
import Data.Version (showVersion)
import Lib.Types.Semver
import Paths_start9_registry (version)
import Startlude
sslPath :: FilePath
sslPath = "/var/ssl"
resourcesDir :: FilePath
resourcesDir = "/var/www/html/resources" -- "./resources" --
registryVersion :: AppVersion
registryVersion = fromJust . parseMaybe parseJSON . String . toS . showVersion $ version
getRegistryHostname :: IsString a => a
getRegistryHostname = "registry.start9labs.com"

View File

@@ -23,8 +23,9 @@ import Yesod.Core
import Foundation
import Lib.Registry
import Lib.Semver
import System.FilePath ((<.>))
import System.FilePath ((<.>), (</>))
import System.Posix.Files (fileSize, getFileStatus)
import Settings
pureLog :: Show a => a -> Handler a
pureLog = liftA2 (*>) ($logInfo . show) pure
@@ -38,13 +39,22 @@ instance Show FileExtension where
show (FileExtension f (Just e)) = f <.> e
getAppsManifestR :: Handler TypedContent
getAppsManifestR = respondSource typePlain $ CB.sourceFile appManifestPath .| awaitForever sendChunkBS
getAppsManifestR = do
AppSettings{..} <- appSettings <$> getYesod
let appResourceDir = resourcesDir </> "apps" </> "apps.yaml"
respondSource typePlain $ CB.sourceFile appResourceDir .| awaitForever sendChunkBS
getSysR :: Extension "" -> Handler TypedContent
getSysR = getApp sysResourceDir
getSysR e = do
AppSettings{..} <- appSettings <$> getYesod
let sysResourceDir = resourcesDir </> "sys"
getApp sysResourceDir e
getAppR :: Extension "s9pk" -> Handler TypedContent
getAppR = getApp appResourceDir
getAppR e = do
AppSettings{..} <- appSettings <$> getYesod
let appResourceDir = resourcesDir </> "apps" </> "apps.yaml"
getApp appResourceDir e
getApp :: KnownSymbol a => FilePath -> Extension a -> Handler TypedContent
getApp rootDir ext = do

View File

@@ -1,5 +1,6 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE RecordWildCards #-}
module Handler.Icons where
@@ -12,10 +13,13 @@ import Yesod.Core
import Foundation
import Lib.Registry
import Settings
import System.FilePath ((</>))
getIconsR :: Extension "png" -> Handler TypedContent
getIconsR ext = do
mPng <- liftIO $ getUnversionedFileFromDir iconsResourceDir ext
AppSettings{..} <- appSettings <$> getYesod
mPng <- liftIO $ getUnversionedFileFromDir (resourcesDir </> "icons") ext
case mPng of
Nothing -> notFound
Just pngPath -> do

View File

@@ -2,6 +2,8 @@
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE RecordWildCards #-}
module Handler.Version where
import Startlude
@@ -14,24 +16,30 @@ import qualified Data.Text as T
import Network.HTTP.Types
import Yesod.Core
import Constants
import Foundation
import Handler.Types.Status
import Lib.Registry
import Lib.Semver
import Lib.Types.Semver
import Settings
import System.FilePath ((</>))
getVersionR :: Handler AppVersionRes
getVersionR = pure . AppVersionRes registryVersion $ Nothing
getVersionR = do
AppSettings{..} <- appSettings <$> getYesod
pure . AppVersionRes registryVersion $ Nothing
getVersionAppR :: Text -> Handler (Maybe AppVersionRes)
getVersionAppR appId = getVersionWSpec appResourceDir appExt
getVersionAppR appId = do
AppSettings{..} <- appSettings <$> getYesod
getVersionWSpec (resourcesDir </> "apps") appExt
where
appExt = Extension (toS appId) :: Extension "s9pk"
getVersionSysR :: Text -> Handler (Maybe AppVersionRes)
getVersionSysR sysAppId = runMaybeT $ do
avr <- MaybeT $ getVersionWSpec sysResourceDir sysExt
AppSettings{..} <- appSettings <$> getYesod
avr <- MaybeT $ getVersionWSpec (resourcesDir </> "sys") sysExt
minComp <- lift $ case sysAppId of
"agent" -> Just <$> meshCompanionCompatibility (appVersionVersion avr)
_ -> pure Nothing

View File

@@ -14,25 +14,9 @@ import System.Directory
import System.FilePath
import Yesod.Core
import Constants
import Lib.Semver
import Lib.Types.Semver
appResourceDir :: FilePath
appResourceDir = resourcesDir </> "apps"
sysResourceDir :: FilePath
sysResourceDir = resourcesDir </> "sys"
iconsResourceDir :: FilePath
iconsResourceDir = resourcesDir </> "icons"
appManifestPath :: FilePath
appManifestPath = appResourceDir </> appManifestFile
appManifestFile :: FilePath
appManifestFile = "apps.yaml"
type Registry = HashMap String (HashMap AppVersion FilePath)
newtype RegisteredAppVersion = RegisteredAppVersion (AppVersion, FilePath) deriving (Eq, Show)

View File

@@ -1,58 +1,49 @@
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
module Lib.Ssl where
import Startlude
import Data.String.Interpolate.IsString
import System.Directory
import System.FilePath
import System.Process
import Constants
import Settings
-- openssl genrsa -out key.pem 2048
-- openssl req -new -key key.pem -out certificate.csr
-- openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem
sslKeyLocation :: FilePath
sslKeyLocation = sslPath </> "key.pem"
sslCsrLocation :: FilePath
sslCsrLocation = sslPath </> "certificate.csr"
sslCertLocation :: FilePath
sslCertLocation = sslPath </> "certificate.pem"
checkForSslCert :: IO Bool
checkForSslCert =
doesPathExist sslKeyLocation <&&> doesPathExist sslCertLocation
generateSslKey :: IO ExitCode
generateSslKey = rawSystem "openssl" ["genrsa", "-out", sslKeyLocation, "2048"]
generateSslCert :: Text -> IO ExitCode
generateSslCert name = rawSystem
"openssl"
["req", "-new", "-key", sslKeyLocation, "-out", sslCsrLocation, "-subj", [i|/CN=#{name}.local|]]
selfSignSslCert :: IO ExitCode
selfSignSslCert = rawSystem
"openssl"
[ "x509"
, "-req"
, "-in"
, sslCsrLocation
, "-signkey"
, sslKeyLocation
, "-out"
, sslCertLocation
]
setupSsl :: IO ()
setupSsl = do
setupSsl :: AppSettings -> IO ()
setupSsl AppSettings{..} = do
exists <- checkForSslCert
unless exists $ do
void $ system $ "mkdir -p " <> sslPath
void generateSslKey
void $ generateSslCert getRegistryHostname
void $ generateSslCert registryHostname
void selfSignSslCert
where
checkForSslCert :: IO Bool
checkForSslCert =
doesPathExist sslKeyLocation <&&> doesPathExist sslCertLocation
generateSslKey :: IO ExitCode
generateSslKey = rawSystem "openssl" ["genrsa", "-out", sslKeyLocation, "2048"]
generateSslCert :: Text -> IO ExitCode
generateSslCert name = rawSystem
"openssl"
["req", "-new", "-key", sslKeyLocation, "-out", sslCsrLocation, "-subj", [i|/CN=#{name}.local|]]
selfSignSslCert :: IO ExitCode
selfSignSslCert = rawSystem
"openssl"
[ "x509"
, "-req"
, "-in"
, sslCsrLocation
, "-signkey"
, sslKeyLocation
, "-out"
, sslCertLocation
]

View File

@@ -10,11 +10,17 @@ module Settings where
import Startlude
import qualified Control.Exception as Exception
import Data.Maybe
import Data.Aeson
import Data.Aeson.Types
import Data.Version (showVersion)
import Data.FileEmbed (embedFile)
import Data.Yaml (decodeEither')
import Network.Wai.Handler.Warp (HostPreference)
import Yesod.Default.Config2 (applyEnvValue, configSettingsYml)
import Paths_start9_registry (version)
import Lib.Types.Semver
import System.FilePath ((</>))
-- | Runtime settings to configure this application. These settings can be
-- loaded from various sources: defaults, environment variables, config files,
@@ -33,6 +39,13 @@ data AppSettings = AppSettings
, appShouldLogAll :: Bool
-- ^ Should all log messages be displayed?
, appCompatibilityPath :: FilePath
, resourcesDir :: FilePath
, sslPath :: FilePath
, registryHostname :: Text
, registryVersion :: AppVersion
, sslKeyLocation :: FilePath
, sslCsrLocation :: FilePath
, sslCertLocation :: FilePath
}
instance FromJSON AppSettings where
@@ -43,7 +56,15 @@ instance FromJSON AppSettings where
appDetailedRequestLogging <- o .:? "detailed-logging" .!= True
appShouldLogAll <- o .:? "should-log-all" .!= False
appCompatibilityPath <- o .: "app-compatibility-path"
resourcesDir <- o .: "resources-path"
sslPath <- o .: "ssl-path"
registryHostname <- o .: "registry-hostname"
let sslKeyLocation = sslPath </> "key.pem"
let sslCsrLocation = sslPath </> "certificate.csr"
let sslCertLocation = sslPath </> "certificate.pem"
let registryVersion = fromJust . parseMaybe parseJSON . String . toS . showVersion $ version
return AppSettings { .. }
-- | Raw bytes at compile time of @config/settings.yml@