cloudy-0.1.0.0: src/Cloudy/LocalConfFile.hs
module Cloudy.LocalConfFile where
import Cloudy.Path (getCloudyConfFilePath)
import Control.Exception (throwIO)
import Data.Aeson (FromJSON (parseJSON), withObject, (.:?), Value (Null), Object)
import Data.Aeson.Types (Parser)
import qualified Data.ByteString as BS
import Data.Text (Text)
import Data.Yaml (decodeEither')
import System.IO.Error (tryIOError, isDoesNotExistError)
data LocalConfFileScalewayOpts = LocalConfFileScalewayOpts
{ accessKey :: Maybe Text
, secretKey :: Maybe Text
, defaultOrganizationId :: Maybe Text
, defaultProjectId :: Maybe Text
, defaultZone :: Maybe Text
, defaultInstanceType :: Maybe Text
, defaultImageId :: Maybe Text
} deriving Show
instance FromJSON LocalConfFileScalewayOpts where
parseJSON :: Value -> Parser LocalConfFileScalewayOpts
parseJSON = withObject "LocalConfFileScalewayOpts" $ \o -> do
accessKey <- o .:? "access_key"
secretKey <- o .:? "secret_key"
defaultOrganizationId <- o .:? "default_organization_id"
defaultProjectId <- o .:? "default_project_id"
defaultZone <- o .:? "default_zone"
defaultInstanceType <- o .:? "default_instance_type"
defaultImageId <- o .:? "default_image_id"
pure
LocalConfFileScalewayOpts
{ accessKey
, secretKey
, defaultOrganizationId
, defaultProjectId
, defaultZone
, defaultInstanceType
, defaultImageId
}
data LocalConfFileOpts = LocalConfFileOpts
{ scaleway :: Maybe LocalConfFileScalewayOpts
} deriving Show
instance FromJSON LocalConfFileOpts where
parseJSON Null = pure defaultLocalConfFileOpts
parseJSON v = withObject "LocalConfFileOpts" parseObj v
where
parseObj :: Object -> Parser LocalConfFileOpts
parseObj o = do
LocalConfFileOpts <$> o .:? "scaleway"
defaultLocalConfFileOpts :: LocalConfFileOpts
defaultLocalConfFileOpts = LocalConfFileOpts { scaleway = Nothing }
readLocalConfFile :: IO LocalConfFileOpts
readLocalConfFile = do
confFilePath <- getCloudyConfFilePath
eitherConfFileRaw <- tryIOError (BS.readFile confFilePath)
case eitherConfFileRaw of
Left ioEx
| isDoesNotExistError ioEx ->
-- conf file does not exist yet on disk, just return the default options
pure defaultLocalConfFileOpts
| otherwise ->
-- We got an IOException that we weren't expecting. Rethrow it.
throwIO ioEx
Right confFileRaw -> do
let eitherConfFileOpts = decodeEither' confFileRaw
case eitherConfFileOpts of
Left parseErr ->
-- We got an error when trying to parse the config file. This is unexpected. Throw it.
throwIO parseErr
Right confFile -> pure confFile