module Ganeti.Config
( LinkIpMap
, loadConfig
, getNodeInstances
, getDefaultNicLink
, getInstancesIpByLink
, getNode
, getInstance
, getInstPrimaryNode
, getInstMinorsForNode
, buildLinkIpInstnameMap
, instNodes
) where
import Data.List (foldl')
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Text.JSON as J
import Ganeti.HTools.JSON
import Ganeti.BasicTypes
import qualified Ganeti.Constants as C
import Ganeti.Objects
type LinkIpMap = M.Map String (M.Map String String)
readConfig :: FilePath -> IO String
readConfig = readFile
parseConfig :: String -> Result ConfigData
parseConfig = fromJResult "parsing configuration" . J.decodeStrict
loadConfig :: FilePath -> IO (Result ConfigData)
loadConfig = fmap parseConfig . readConfig
computeDiskNodes :: Disk -> S.Set String
computeDiskNodes dsk =
case diskLogicalId dsk of
LIDDrbd8 nodeA nodeB _ _ _ _ -> S.fromList [nodeA, nodeB]
_ -> S.empty
instDiskNodes :: Instance -> S.Set String
instDiskNodes = S.unions . map computeDiskNodes . instDisks
instNodes :: Instance -> S.Set String
instNodes inst = instPrimaryNode inst `S.insert` instDiskNodes inst
instSecondaryNodes :: Instance -> S.Set String
instSecondaryNodes inst =
instPrimaryNode inst `S.delete` instDiskNodes inst
getNodeInstances :: ConfigData -> String -> ([Instance], [Instance])
getNodeInstances cfg nname =
let all_inst = M.elems . configInstances $ cfg
pri_inst = filter ((== nname) . instPrimaryNode) all_inst
sec_inst = filter ((nname `S.member`) . instSecondaryNodes) all_inst
in (pri_inst, sec_inst)
getDefaultNicLink :: ConfigData -> String
getDefaultNicLink =
nicpLink . (M.! C.ppDefault) . clusterNicparams . configCluster
getInstancesIpByLink :: LinkIpMap -> String -> [String]
getInstancesIpByLink linkipmap link =
M.keys $ M.findWithDefault M.empty link linkipmap
getItem :: String -> String -> M.Map String a -> Result a
getItem kind name allitems = do
let lresult = lookupName (M.keys allitems) name
err = \details -> Bad $ kind ++ " name " ++ name ++ " " ++ details
fullname <- case lrMatchPriority lresult of
PartialMatch -> Ok $ lrContent lresult
ExactMatch -> Ok $ lrContent lresult
MultipleMatch -> err "has multiple matches"
FailMatch -> err "not found"
maybe (err "not found after successfull match?!") Ok $
M.lookup fullname allitems
getNode :: ConfigData -> String -> Result Node
getNode cfg name = getItem "Node" name (configNodes cfg)
getInstance :: ConfigData -> String -> Result Instance
getInstance cfg name = getItem "Instance" name (configInstances cfg)
getInstPrimaryNode :: ConfigData -> String -> Result Node
getInstPrimaryNode cfg name =
getInstance cfg name >>= return . instPrimaryNode >>= getNode cfg
getDrbdMinorsForNode :: String -> Disk -> [(Int, String)]
getDrbdMinorsForNode node disk =
let child_minors = concatMap (getDrbdMinorsForNode node) (diskChildren disk)
this_minors =
case diskLogicalId disk of
LIDDrbd8 nodeA nodeB _ minorA minorB _
| nodeA == node -> [(minorA, nodeB)]
| nodeB == node -> [(minorB, nodeA)]
_ -> []
in this_minors ++ child_minors
rolePrimary :: String
rolePrimary = "primary"
roleSecondary :: String
roleSecondary = "secondary"
getInstMinorsForNode :: String -> Instance
-> [(String, Int, String, String, String, String)]
getInstMinorsForNode node inst =
let role = if node == instPrimaryNode inst
then rolePrimary
else roleSecondary
iname = instName inst
in concatMap (\(idx, dsk) ->
[(node, minor, iname, "disk/" ++ show idx, role, peer)
| (minor, peer) <- getDrbdMinorsForNode node dsk]) .
zip [(0::Int)..] . instDisks $ inst
buildLinkIpInstnameMap :: ConfigData -> LinkIpMap
buildLinkIpInstnameMap cfg =
let cluster = configCluster cfg
instances = M.elems . configInstances $ cfg
defparams = (M.!) (clusterNicparams cluster) C.ppDefault
nics = concatMap (\i -> [(instName i, nic) | nic <- instNics i])
instances
in foldl' (\accum (iname, nic) ->
let pparams = nicNicparams nic
fparams = fillNICParams defparams pparams
link = nicpLink fparams
in case nicIp nic of
Nothing -> accum
Just ip -> let oldipmap = M.findWithDefault (M.empty)
link accum
newipmap = M.insert ip iname oldipmap
in M.insert link newipmap accum
) M.empty nics