X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/b7b29191140fccb55fd2c3ffd70cef76862a1412..6c7448bb66760c6a218edccbc4a9e1bf113c1ae5:/Ganeti/HTools/Rapi.hs diff --git a/Ganeti/HTools/Rapi.hs b/Ganeti/HTools/Rapi.hs index 84332f6..64c6a23 100644 --- a/Ganeti/HTools/Rapi.hs +++ b/Ganeti/HTools/Rapi.hs @@ -4,7 +4,7 @@ {- -Copyright (C) 2009 Google Inc. +Copyright (C) 2009, 2010 Google Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,6 +39,7 @@ import Text.Printf (printf) import Ganeti.HTools.Utils import Ganeti.HTools.Loader import Ganeti.HTools.Types +import qualified Ganeti.HTools.Group as Group import qualified Ganeti.HTools.Node as Node import qualified Ganeti.HTools.Instance as Instance @@ -70,12 +71,17 @@ getInstances ktn body = mapM (parseInstance ktn . fromJSObject) -- | Parse a node list in JSON format. -getNodes :: String -> Result [(String, Node.Node)] -getNodes body = loadJSArray "Parsing node data" body >>= - mapM (parseNode . fromJSObject) +getNodes :: NameAssoc -> String -> Result [(String, Node.Node)] +getNodes ktg body = loadJSArray "Parsing node data" body >>= + mapM (parseNode ktg . fromJSObject) + +-- | Parse a group list in JSON format. +getGroups :: String -> Result [(String, Group.Group)] +getGroups body = loadJSArray "Parsing group data" body >>= + mapM (parseGroup . fromJSObject) -- | Construct an instance from a JSON object. -parseInstance :: [(String, Ndx)] +parseInstance :: NameAssoc -> [(String, JSValue)] -> Result (String, Instance.Instance) parseInstance ktn a = do @@ -99,13 +105,13 @@ parseInstance ktn a = do return (name, inst) -- | Construct a node from a JSON object. -parseNode :: [(String, JSValue)] -> Result (String, Node.Node) -parseNode a = do +parseNode :: NameAssoc -> [(String, JSValue)] -> Result (String, Node.Node) +parseNode ktg a = do name <- tryFromObj "Parsing new node" a "name" let extract s = tryFromObj ("Node '" ++ name ++ "'") a s offline <- extract "offline" drained <- extract "drained" - guuid <- extract "group.uuid" + guuid <- extract "group.uuid" >>= lookupGroup ktg name node <- (if offline || drained then return $ Node.create name 0 0 0 0 0 0 True guuid else do @@ -119,28 +125,40 @@ parseNode a = do dtotal dfree ctotal False guuid) return (name, node) +-- | Construct a group from a JSON object. +parseGroup :: [(String, JSValue)] -> Result (String, Group.Group) +parseGroup a = do + name <- tryFromObj "Parsing new group" a "name" + let extract s = tryFromObj ("Group '" ++ name ++ "'") a s + uuid <- extract "uuid" + apol <- extract "alloc_policy" + return (uuid, Group.create name uuid apol) + -- | Loads the raw cluster data from an URL. readData :: String -- ^ Cluster or URL to use as source - -> IO (Result String, Result String, Result String) + -> IO (Result String, Result String, Result String, Result String) readData master = do let url = formatHost master + group_body <- getUrl $ printf "%s/2/groups?bulk=1" url node_body <- getUrl $ printf "%s/2/nodes?bulk=1" url inst_body <- getUrl $ printf "%s/2/instances?bulk=1" url tags_body <- getUrl $ printf "%s/2/tags" url - return (node_body, inst_body, tags_body) + return (group_body, node_body, inst_body, tags_body) -- | Builds the cluster data from the raw Rapi content -parseData :: (Result String, Result String, Result String) - -> Result (Node.AssocList, Instance.AssocList, [String]) -parseData (node_body, inst_body, tags_body) = do - node_data <- node_body >>= getNodes +parseData :: (Result String, Result String, Result String, Result String) + -> Result (Group.List, Node.List, Instance.List, [String]) +parseData (group_body, node_body, inst_body, tags_body) = do + group_data <- group_body >>= getGroups + let (group_names, group_idx) = assignIndices group_data + node_data <- node_body >>= getNodes group_names let (node_names, node_idx) = assignIndices node_data inst_data <- inst_body >>= getInstances node_names let (_, inst_idx) = assignIndices inst_data tags_data <- tags_body >>= (fromJResult "Parsing tags data" . decodeStrict) - return (node_idx, inst_idx, tags_data) + return (group_idx, node_idx, inst_idx, tags_data) -- | Top level function for data loading loadData :: String -- ^ Cluster or URL to use as source - -> IO (Result (Node.AssocList, Instance.AssocList, [String])) + -> IO (Result (Group.List, Node.List, Instance.List, [String])) loadData master = readData master >>= return . parseData