cloudy-0.1.0.0: src/Cloudy/Cmd/List.hs
{-# LANGUAGE OverloadedRecordDot #-}
module Cloudy.Cmd.List where
import Cloudy.Cli (ListCliOpts (..))
import Cloudy.Db (CloudyInstance (..), InstanceInfo (..), ScalewayInstance (..), cloudyInstanceFromInstanceInfo, findAllInstanceInfos, withCloudyDb, unCloudyInstanceId)
import Cloudy.InstanceSetup.Types (InstanceSetup (..))
import Cloudy.LocalConfFile (LocalConfFileOpts)
import Cloudy.Table (Table (..), printTable, Align (..))
import Data.List (sortOn)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Text (Text, pack)
import Data.Time (defaultTimeLocale, formatTime, UTCTime, utcToZonedTime, TimeZone, getCurrentTimeZone)
import Data.Void (absurd)
runList :: LocalConfFileOpts -> ListCliOpts -> IO ()
runList _localConfFileOpts _opts = do
instInfos <- withCloudyDb $ \conn -> findAllInstanceInfos conn
displayInstanceInfos instInfos
displayInstanceInfos :: [InstanceInfo] -> IO ()
displayInstanceInfos instInfos = do
tz <- getCurrentTimeZone
let sortByCloudyInstId = sortOn (\instInfo -> (cloudyInstanceFromInstanceInfo instInfo).id) instInfos
case sortByCloudyInstId of
[] -> putStrLn "No instances currently running."
(hInst : tInsts) -> do
let instTable = mkTable tz (hInst :| tInsts)
printTable instTable
mkTable :: TimeZone -> NonEmpty InstanceInfo -> Table
mkTable tz instanceTypes =
Table
{ tableHeaders =
(RightJustified, "instance id") :|
[ (LeftJustified, "instance name")
, (LeftJustified, "created date")
, (LeftJustified, "cloud")
, (LeftJustified, "zone")
, (LeftJustified, "ip")
, (LeftJustified, "instance setup")
]
, tableBodyRows = fmap (mkRow tz) instanceTypes
}
mkRow :: TimeZone -> InstanceInfo -> NonEmpty Text
mkRow tz = \case
CloudyAwsInstance _ void -> absurd void
CloudyScalewayInstance cloudyInstance scalewayInstance ->
pack (show (unCloudyInstanceId cloudyInstance.id)) :|
[ cloudyInstance.name
, formatDateTime cloudyInstance.createdAt
, "scaleway"
, scalewayInstance.scalewayZone
, scalewayInstance.scalewayIpAddress
, prettyInstanceSetup cloudyInstance.instanceSetup
]
where
formatDateTime :: Maybe UTCTime -> Text
formatDateTime = \case
Nothing -> "ERROR: expecting cloudy instance to have created_at value"
Just createdAt ->
pack $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M" $ utcToZonedTime tz createdAt
prettyInstanceSetup :: Maybe InstanceSetup -> Text
prettyInstanceSetup = \case
Nothing -> "(none)"
Just instSetup -> instSetup.name