X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/3f6af65cbc62ec654f491b7bc0e154287adac7ad..1c035cb359448b5363860df55509f217df18a22a:/Ganeti/HTools/IAlloc.hs diff --git a/Ganeti/HTools/IAlloc.hs b/Ganeti/HTools/IAlloc.hs index d3a7e98..b5391f6 100644 --- a/Ganeti/HTools/IAlloc.hs +++ b/Ganeti/HTools/IAlloc.hs @@ -11,74 +11,94 @@ module Ganeti.HTools.IAlloc import Data.Either () import Data.Maybe import Control.Monad -import Text.JSON +import Text.JSON (JSObject, JSValue(JSBool, JSString, JSArray), + makeObj, encodeStrict, decodeStrict, + fromJSObject, toJSString) import Text.Printf (printf) import Ganeti.HTools.Utils +import qualified Ganeti.HTools.Node as Node +import qualified Ganeti.HTools.Instance as Instance -parseInstance :: String -> JSObject JSValue -> Either String String +data RqType + = Allocate + | Relocate + deriving (Eq, Show) + +data Request + = RqAlloc String String String + | RqReloc String String String + +parseInstance :: String -> JSObject JSValue -> Result String parseInstance n a = - let name = Right n + let name = Ok n disk = case getIntElement "disk_usage" a of - Left _ -> let all_d = getListElement "disks" a `combineEithers` - asObjectList - szd = all_d `combineEithers` - (ensureEitherList . - map (getIntElement "size")) - sze = applyEither1 (map (+128)) szd - szf = applyEither1 sum sze + Bad _ -> let all_d = getListElement "disks" a >>= asObjectList + szd = all_d >>= + (sequence . + map (getIntElement "size")) + sze = liftM (map (+128)) szd + szf = liftM sum sze in szf - Right x -> Right x + x@(Ok _) -> x nodes = getListElement "nodes" a - pnode = eitherListHead nodes - `combineEithers` readEitherString - snode = applyEither1 (head . tail) nodes - `combineEithers` readEitherString + pnode = liftM head nodes >>= readEitherString + snode = liftM (head . tail) nodes >>= readEitherString mem = getIntElement "memory" a - running = Right "running" --getStringElement "status" a + running = Ok "running" --getStringElement "status" a in - concatEitherElems name $ - concatEitherElems (show `applyEither1` mem) $ - concatEitherElems (show `applyEither1` disk) $ - concatEitherElems running $ - concatEitherElems pnode snode + name |+ (show `liftM` mem) |+ + (show `liftM` disk) |+ running |+ pnode |+ snode -parseNode :: String -> JSObject JSValue -> Either String String +parseNode :: String -> JSObject JSValue -> Result String parseNode n a = - let name = Right n + let name = Ok n mtotal = getIntElement "total_memory" a mnode = getIntElement "reserved_memory" a mfree = getIntElement "free_memory" a dtotal = getIntElement "total_disk" a dfree = getIntElement "free_disk" a - in concatEitherElems name $ - concatEitherElems (show `applyEither1` mtotal) $ - concatEitherElems (show `applyEither1` mnode) $ - concatEitherElems (show `applyEither1` mfree) $ - concatEitherElems (show `applyEither1` dtotal) - (show `applyEither1` dfree) + in name |+ (show `liftM` mtotal) |+ + (show `liftM` mnode) |+ + (show `liftM` mfree) |+ + (show `liftM` dtotal) |+ + (show `liftM` dfree) + +validateRequest :: String -> Result RqType +validateRequest rq = + case rq of + "allocate" -> Ok Allocate + "relocate" -> Ok Relocate + _ -> Bad ("Invalid request type '" ++ rq ++ "'") -parseData :: String -> Either String (String, String) +parseData :: String -> Result Request parseData body = - let - decoded = resultToEither $ decodeStrict body - obj = decoded -- decoded `combineEithers` fromJSObject - request = obj `combineEithers` getObjectElement "request" - rname = request `combineEithers` getStringElement "name" - ilist = obj `combineEithers` getObjectElement "instances" - nlist = obj `combineEithers` getObjectElement "nodes" - idata = applyEither1 fromJSObject ilist - ndata = applyEither1 fromJSObject nlist - iobj = idata `combineEithers` (ensureEitherList . - map (\(x,y) -> - asJSObject y `combineEithers` - parseInstance x)) - ilines = iobj `combineEithers` (Right . unlines) - nobj = ndata `combineEithers` (ensureEitherList . - map (\(x,y) -> - asJSObject y `combineEithers` - parseNode x)) - nlines = nobj `combineEithers` (Right . unlines) - in applyEither2 (,) nlines ilines + do + decoded <- fromJResult $ decodeStrict body + let obj = decoded -- decoded `combineEithers` fromJSObject + -- request parser + request <- getObjectElement "request" obj + rname <- getStringElement "name" request + rtype <- getStringElement "type" request >>= validateRequest + inew <- (\x -> if x == Allocate then parseInstance rname request + else Ok "") rtype + -- existing intstance parsing + ilist <- getObjectElement "instances" obj + let idata = fromJSObject ilist + iobj <- (sequence . map (\(x,y) -> asJSObject y >>= parseInstance x)) + idata + let ilines = unlines iobj + -- existing node parsing + nlist <- getObjectElement "nodes" obj + let ndata = fromJSObject nlist + nobj <- (sequence . map (\(x,y) -> asJSObject y >>= parseNode x)) + ndata + let nlines = unlines nobj + return $ (\ r nl il inew rnam -> + case r of + Allocate -> RqAlloc inew nl il + Relocate -> RqReloc rnam nl il) + rtype nlines ilines inew rname + formatResponse :: Bool -> String -> [String] -> String formatResponse success info nodes =