module Ganeti.Query.Common
( NoDataRuntime(..)
, rsNoData
, rsUnavail
, rsNormal
, rsMaybeNoData
, rsMaybeUnavail
, rsErrorNoData
, rsErrorMaybeUnavail
, rsUnknown
, missingRuntime
, rpcErrorToStatus
, timeStampFields
, uuidFields
, serialFields
, tagsFields
, dictFieldGetter
, buildNdParamField
, buildBeParamField
, buildHvParamField
, getDefaultHypervisorSpec
, getHvParamsFromCluster
, aliasFields
) where
import Control.Monad (guard)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import Text.JSON (JSON, showJSON)
import Ganeti.BasicTypes
import qualified Ganeti.Constants as C
import Ganeti.Config
import Ganeti.Errors
import Ganeti.JSON
import Ganeti.Objects
import Ganeti.Rpc
import Ganeti.Query.Language
import Ganeti.Query.Types
import Ganeti.Types
data NoDataRuntime = NoDataRuntime
vTypeToQFT :: VType -> FieldType
vTypeToQFT VTypeString = QFTOther
vTypeToQFT VTypeMaybeString = QFTOther
vTypeToQFT VTypeBool = QFTBool
vTypeToQFT VTypeSize = QFTUnit
vTypeToQFT VTypeInt = QFTNumber
vTypeToQFT VTypeFloat = QFTNumberFloat
rsNoData :: ResultEntry
rsNoData = ResultEntry RSNoData Nothing
rsUnavail :: ResultEntry
rsUnavail = ResultEntry RSUnavail Nothing
rsNormal :: (JSON a) => a -> ResultEntry
rsNormal a = ResultEntry RSNormal $ Just (showJSON a)
rsMaybeNoData :: (JSON a) => Maybe a -> ResultEntry
rsMaybeNoData = maybe rsNoData rsNormal
rsErrorNoData :: (JSON a) => ErrorResult a -> ResultEntry
rsErrorNoData res = case res of
Ok x -> rsNormal x
Bad _ -> rsNoData
rsMaybeUnavail :: (JSON a) => Maybe a -> ResultEntry
rsMaybeUnavail = maybe rsUnavail rsNormal
rsErrorMaybeUnavail :: (JSON a) => ErrorResult (Maybe a) -> ResultEntry
rsErrorMaybeUnavail res =
case res of
Ok x -> rsMaybeUnavail x
Bad _ -> rsNoData
rsUnknown :: ResultEntry
rsUnknown = ResultEntry RSUnknown Nothing
missingRuntime :: FieldGetter a b
missingRuntime = FieldRuntime (\_ _ -> ResultEntry RSNoData Nothing)
rpcErrorToStatus :: RpcError -> ResultStatus
rpcErrorToStatus OfflineNodeError = RSOffline
rpcErrorToStatus _ = RSNoData
timeStampFields :: (TimeStampObject a) => FieldList a b
timeStampFields =
[ (FieldDefinition "ctime" "CTime" QFTTimestamp "Creation timestamp",
FieldSimple (rsNormal . TimeAsDoubleJSON . cTimeOf), QffNormal)
, (FieldDefinition "mtime" "MTime" QFTTimestamp "Modification timestamp",
FieldSimple (rsNormal . TimeAsDoubleJSON . mTimeOf), QffNormal)
]
uuidFields :: (UuidObject a) => String -> FieldList a b
uuidFields name =
[ (FieldDefinition "uuid" "UUID" QFTText (name ++ " UUID"),
FieldSimple (rsNormal . uuidOf), QffNormal) ]
serialFields :: (SerialNoObject a) => String -> FieldList a b
serialFields name =
[ (FieldDefinition "serial_no" "SerialNo" QFTNumber
(name ++ " object serial number, incremented on each modification"),
FieldSimple (rsNormal . serialOf), QffNormal) ]
tagsFields :: (TagsObject a) => FieldList a b
tagsFields =
[ (FieldDefinition "tags" "Tags" QFTOther "Tags",
FieldSimple (rsNormal . tagsOf), QffNormal) ]
dictFieldGetter :: (DictObject a) => String -> Maybe a -> ResultEntry
dictFieldGetter k = maybe rsNoData (rsMaybeNoData . lookup k . toDict)
ndParamTypes :: Map.Map String FieldType
ndParamTypes = Map.map vTypeToQFT C.ndsParameterTypes
ndParamTitles :: Map.Map String FieldTitle
ndParamTitles = C.ndsParameterTitles
ndParamGetter :: (NdParamObject a) =>
String
-> ConfigData -> a -> ResultEntry
ndParamGetter field config =
dictFieldGetter field . getNdParamsOf config
buildNdParamField :: (NdParamObject a) => String -> FieldData a b
buildNdParamField =
buildParamField "ndp" "node" ndParamTitles ndParamTypes ndParamGetter
beParamTypes :: Map.Map String FieldType
beParamTypes = Map.map vTypeToQFT C.besParameterTypes
buildBeParamField :: (String -> ConfigData -> a -> ResultEntry)
-> String
-> FieldData a b
buildBeParamField =
buildParamField "be" "backend" C.besParameterTitles beParamTypes
hvParamTypes :: Map.Map String FieldType
hvParamTypes = Map.map vTypeToQFT C.hvsParameterTypes
buildHvParamField :: (String -> ConfigData -> a -> ResultEntry)
-> String
-> FieldData a b
buildHvParamField =
buildParamField "hv" "hypervisor" C.hvsParameterTitles hvParamTypes
buildParamField :: String
-> String
-> Map.Map String String
-> Map.Map String FieldType
-> (String -> ConfigData -> a -> ResultEntry)
-> String
-> FieldData a b
buildParamField prefix paramGroupName titleMap typeMap getter field =
let full_name = prefix ++ "/" ++ field
title = fromMaybe full_name $ field `Map.lookup` titleMap
qft = fromMaybe QFTOther $ field `Map.lookup` typeMap
desc = "The \"" ++ field ++ "\" " ++ paramGroupName ++ " parameter"
in ( FieldDefinition full_name title qft desc
, FieldConfig (getter field), QffNormal
)
getDefaultHypervisorSpec :: ConfigData -> (Hypervisor, HvParams)
getDefaultHypervisorSpec cfg = (hv, getHvParamsFromCluster cfg hv)
where hv = getDefaultHypervisor cfg
getHvParamsFromCluster :: ConfigData -> Hypervisor -> HvParams
getHvParamsFromCluster cfg hv =
fromMaybe (GenericContainer Map.empty) .
Map.lookup hv .
fromContainer . clusterHvparams $ configCluster cfg
aliasFields :: [(FieldName, FieldName)] -> FieldList a b -> FieldList a b
aliasFields aliases fieldList = fieldList ++ do
alias <- aliases
(FieldDefinition name d1 d2 d3, v1, v2) <- fieldList
guard (snd alias == name)
return (FieldDefinition (fst alias) d1 d2 d3, v1, v2)