X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/040afc3532b84536c926a1bafa4252f9364e260e..d71d0a1dca102d0ef8b035a061d51c4e69d8fd19:/Ganeti/HTools/Rapi.hs diff --git a/Ganeti/HTools/Rapi.hs b/Ganeti/HTools/Rapi.hs index 5cfc42b..fc6a46c 100644 --- a/Ganeti/HTools/Rapi.hs +++ b/Ganeti/HTools/Rapi.hs @@ -2,6 +2,27 @@ -} +{- + +Copyright (C) 2009 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 +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. + +-} + module Ganeti.HTools.Rapi ( loadData @@ -17,10 +38,11 @@ import Text.Printf (printf) import Ganeti.HTools.Utils import Ganeti.HTools.Loader +import Ganeti.HTools.Types import qualified Ganeti.HTools.Node as Node import qualified Ganeti.HTools.Instance as Instance --- | Read an URL via curl and return the body if successful +-- | Read an URL via curl and return the body if successful. getUrl :: (Monad m) => String -> IO (m String) getUrl url = do (code, body) <- curlGetString url [CurlSSLVerifyPeer False, @@ -30,68 +52,68 @@ getUrl url = do _ -> fail $ printf "Curl error for '%s', error %s" url (show code)) --- | Append the default port if not passed in +-- | Append the default port if not passed in. formatHost :: String -> String formatHost master = if elem ':' master then master else "https://" ++ master ++ ":5080" +-- | Parse a instance list in JSON format. getInstances :: NameAssoc -> String -> Result [(String, Instance.Instance)] -getInstances ktn body = do - arr <- loadJSArray body - ilist <- mapM (parseInstance ktn) arr - return ilist +getInstances ktn body = loadJSArray body >>= mapM (parseInstance ktn) +-- | Parse a node list in JSON format. getNodes :: String -> Result [(String, Node.Node)] -getNodes body = do - arr <- loadJSArray body - nlist <- mapM parseNode arr - return nlist +getNodes body = loadJSArray body >>= mapM parseNode -parseInstance :: [(String, Int)] +-- | Construct an instance from a JSON object. +parseInstance :: [(String, Ndx)] -> JSObject JSValue -> Result (String, Instance.Instance) parseInstance ktn a = do name <- fromObj "name" a disk <- fromObj "disk_usage" a mem <- fromObj "beparams" a >>= fromObj "memory" + vcpus <- fromObj "beparams" a >>= fromObj "vcpus" pnode <- fromObj "pnode" a >>= lookupNode ktn name - snodes <- getListElement "snodes" a + snodes <- fromObj "snodes" a snode <- (if null snodes then return Node.noSecondary else readEitherString (head snodes) >>= lookupNode ktn name) running <- fromObj "status" a - let inst = Instance.create mem disk running pnode snode + let inst = Instance.create name mem disk vcpus running pnode snode return (name, inst) +-- | Construct a node from a JSON object. parseNode :: JSObject JSValue -> Result (String, Node.Node) parseNode a = do name <- fromObj "name" a offline <- fromObj "offline" a - node <- (case offline of - True -> return $ Node.create 0 0 0 0 0 True - _ -> do - drained <- fromObj "drained" a - mtotal <- fromObj "mtotal" a - mnode <- fromObj "mnode" a - mfree <- fromObj "mfree" a - dtotal <- fromObj "dtotal" a - dfree <- fromObj "dfree" a - return $ Node.create mtotal mnode mfree - dtotal dfree (offline || drained)) + node <- (if offline + then return $ Node.create name 0 0 0 0 0 0 True + else do + drained <- fromObj "drained" a + mtotal <- fromObj "mtotal" a + mnode <- fromObj "mnode" a + mfree <- fromObj "mfree" a + dtotal <- fromObj "dtotal" a + dfree <- fromObj "dfree" a + ctotal <- fromObj "ctotal" a + return $ Node.create name mtotal mnode mfree + dtotal dfree ctotal (offline || drained)) return (name, node) -loadData :: String -- ^ Cluster/URL to use as source - -> IO (Result (NameAssoc, Node.AssocList, - NameAssoc, Instance.AssocList)) +-- | Builds the cluster data from an URL. +loadData :: String -- ^ Cluster or URL to use as source + -> IO (Result (Node.AssocList, Instance.AssocList)) loadData master = do -- IO monad let url = formatHost master node_body <- getUrl $ printf "%s/2/nodes?bulk=1" url inst_body <- getUrl $ printf "%s/2/instances?bulk=1" url return $ do -- Result monad node_data <- node_body >>= getNodes - let (node_names, node_idx) = assignIndices Node.setIdx node_data + let (node_names, node_idx) = assignIndices node_data inst_data <- inst_body >>= getInstances node_names - let (inst_names, inst_idx) = assignIndices Instance.setIdx inst_data - return (node_names, node_idx, inst_names, inst_idx) + let (_, inst_idx) = assignIndices inst_data + return (node_idx, inst_idx)