1 {-| Implementation of the iallocator interface.
5 module Ganeti.HTools.IAlloc
14 import Text.JSON (JSObject, JSValue(JSBool, JSString, JSArray),
15 makeObj, encodeStrict, decodeStrict,
16 fromJSObject, toJSString)
17 import Text.Printf (printf)
18 import Ganeti.HTools.Utils
19 import qualified Ganeti.HTools.Node as Node
20 import qualified Ganeti.HTools.Instance as Instance
28 = RqAlloc String String String
29 | RqReloc String String String
31 parseInstance :: String -> JSObject JSValue -> Result String
34 disk = case getIntElement "disk_usage" a of
35 Bad _ -> let all_d = getListElement "disks" a >>= asObjectList
38 map (getIntElement "size"))
39 sze = liftM (map (+128)) szd
43 nodes = getListElement "nodes" a
44 pnode = liftM head nodes >>= readEitherString
45 snode = liftM (head . tail) nodes >>= readEitherString
46 mem = getIntElement "memory" a
47 running = Ok "running" --getStringElement "status" a
49 name |+ (show `liftM` mem) |+
50 (show `liftM` disk) |+ running |+ pnode |+ snode
52 parseNode :: String -> JSObject JSValue -> Result String
55 mtotal = getIntElement "total_memory" a
56 mnode = getIntElement "reserved_memory" a
57 mfree = getIntElement "free_memory" a
58 dtotal = getIntElement "total_disk" a
59 dfree = getIntElement "free_disk" a
60 in name |+ (show `liftM` mtotal) |+
61 (show `liftM` mnode) |+
62 (show `liftM` mfree) |+
63 (show `liftM` dtotal) |+
66 validateRequest :: String -> Result RqType
69 "allocate" -> Ok Allocate
70 "relocate" -> Ok Relocate
71 _ -> Bad ("Invalid request type '" ++ rq ++ "'")
73 parseData :: String -> Result Request
76 decoded <- fromJResult $ decodeStrict body
77 let obj = decoded -- decoded `combineEithers` fromJSObject
79 request <- getObjectElement "request" obj
80 rname <- getStringElement "name" request
81 rtype <- getStringElement "type" request >>= validateRequest
82 inew <- (\x -> if x == Allocate then parseInstance rname request
84 -- existing intstance parsing
85 ilist <- getObjectElement "instances" obj
86 let idata = fromJSObject ilist
87 iobj <- (sequence . map (\(x,y) -> asJSObject y >>= parseInstance x))
89 let ilines = unlines iobj
90 -- existing node parsing
91 nlist <- getObjectElement "nodes" obj
92 let ndata = fromJSObject nlist
93 nobj <- (sequence . map (\(x,y) -> asJSObject y >>= parseNode x))
95 let nlines = unlines nobj
96 return $ (\ r nl il inew rnam ->
98 Allocate -> RqAlloc inew nl il
99 Relocate -> RqReloc rnam nl il)
100 rtype nlines ilines inew rname
103 formatResponse :: Bool -> String -> [String] -> String
104 formatResponse success info nodes =
106 e_success = ("success", JSBool success)
107 e_info = ("info", JSString . toJSString $ info)
108 e_nodes = ("nodes", JSArray $ map (JSString . toJSString) nodes)
109 in encodeStrict $ makeObj [e_success, e_info, e_nodes]