module Ganeti.Query.Network
( getGroupConnection
, getNetworkUuid
, instIsConnected
, Runtime
, fieldsMap
, collectLiveData
) where
import qualified Data.Map as Map
import Data.Maybe (fromMaybe, mapMaybe)
import Data.List (find, foldl', intercalate)
import Ganeti.JSON
import Ganeti.Network
import Ganeti.Objects
import Ganeti.Query.Language
import Ganeti.Query.Common
import Ganeti.Query.Types
import Ganeti.Types
data Runtime = Runtime
networkFields :: FieldList Network Runtime
networkFields =
[ (FieldDefinition "name" "Network" QFTText "Name",
FieldSimple (rsNormal . networkName), QffNormal)
, (FieldDefinition "network" "Subnet" QFTText "IPv4 subnet",
FieldSimple (rsNormal . networkNetwork), QffNormal)
, (FieldDefinition "gateway" "Gateway" QFTOther "IPv4 gateway",
FieldSimple (rsMaybeUnavail . networkGateway), QffNormal)
, (FieldDefinition "network6" "IPv6Subnet" QFTOther "IPv6 subnet",
FieldSimple (rsMaybeUnavail . networkNetwork6), QffNormal)
, (FieldDefinition "gateway6" "IPv6Gateway" QFTOther "IPv6 gateway",
FieldSimple (rsMaybeUnavail . networkGateway6), QffNormal)
, (FieldDefinition "mac_prefix" "MacPrefix" QFTOther "MAC address prefix",
FieldSimple (rsMaybeUnavail . networkMacPrefix), QffNormal)
, (FieldDefinition "free_count" "FreeCount" QFTNumber "Number of available\
\ addresses",
FieldSimple (rsMaybeNoData . fmap getFreeCount . createAddressPool),
QffNormal)
, (FieldDefinition "map" "Map" QFTText "Actual mapping",
FieldSimple (rsMaybeNoData . fmap getMap . createAddressPool),
QffNormal)
, (FieldDefinition "reserved_count" "ReservedCount" QFTNumber
"Number of reserved addresses",
FieldSimple (rsMaybeNoData . fmap getReservedCount . createAddressPool),
QffNormal)
, (FieldDefinition "group_list" "GroupList" QFTOther
"List of nodegroups (group name, NIC mode, NIC link)",
FieldConfig (\cfg -> rsNormal . getGroupConnections cfg . networkUuid),
QffNormal)
, (FieldDefinition "group_cnt" "NodeGroups" QFTNumber "Number of nodegroups",
FieldConfig (\cfg -> rsNormal . length . getGroupConnections cfg
. networkUuid), QffNormal)
, (FieldDefinition "inst_list" "InstanceList" QFTOther "List of instances",
FieldConfig (\cfg -> rsNormal . getInstances cfg . networkUuid),
QffNormal)
, (FieldDefinition "inst_cnt" "Instances" QFTNumber "Number of instances",
FieldConfig (\cfg -> rsNormal . length . getInstances cfg
. networkUuid), QffNormal)
, (FieldDefinition "external_reservations" "ExternalReservations" QFTText
"External reservations",
FieldSimple getExtReservationsString, QffNormal)
] ++
timeStampFields ++
uuidFields "Network" ++
serialFields "Network" ++
tagsFields
fieldsMap :: FieldMap Network Runtime
fieldsMap =
Map.fromList $ map (\v@(f, _, _) -> (fdefName f, v)) networkFields
getGroupConnections :: ConfigData -> String -> [(String, String, String)]
getGroupConnections cfg network_uuid =
mapMaybe (getGroupConnection network_uuid)
((Map.elems . fromContainer . configNodegroups) cfg)
getGroupConnection :: String -> NodeGroup -> Maybe (String, String, String)
getGroupConnection network_uuid group =
let networks = fromContainer . groupNetworks $ group
in case Map.lookup network_uuid networks of
Nothing -> Nothing
Just net ->
Just (groupName group, getNicMode net, getNicLink net)
getNicMode :: PartialNicParams -> String
getNicMode nic_params =
maybe "-" nICModeToRaw $ nicpModeP nic_params
getNicLink :: PartialNicParams -> String
getNicLink nic_params = fromMaybe "-" (nicpLinkP nic_params)
getInstances :: ConfigData -> String -> [String]
getInstances cfg network_uuid =
map instName (filter (instIsConnected cfg network_uuid)
((Map.elems . fromContainer . configInstances) cfg))
instIsConnected :: ConfigData -> String -> Instance -> Bool
instIsConnected cfg network_uuid inst =
network_uuid `elem` mapMaybe (getNetworkUuid cfg)
(mapMaybe nicNetwork (instNics inst))
getNetworkUuid :: ConfigData -> String -> Maybe String
getNetworkUuid cfg name =
let net = find (\n -> name == fromNonEmpty (networkName n))
((Map.elems . fromContainer . configNetworks) cfg)
in fmap networkUuid net
getReservations :: Ip4Network -> String -> [Ip4Address]
getReservations (Ip4Network net _) =
reverse .
fst .
foldl' (\(accu, addr) c ->
let addr' = nextIp4Address addr
accu' = case c of
'1' -> addr:accu
'0' -> accu
_ ->
accu
in (accu', addr')) ([], net)
getExtReservationsString :: Network -> ResultEntry
getExtReservationsString net =
let addrs = getReservations (networkNetwork net)
(fromMaybe "" $ networkExtReservations net)
in rsNormal . intercalate ", " $ map show addrs
collectLiveData :: Bool -> ConfigData -> [Network] -> IO [(Network, Runtime)]
collectLiveData _ _ = return . map (\n -> (n, Runtime))