Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / IAlloc.hs @ 144f190b

History | View | Annotate | Download (4.1 kB)

1
{-| Implementation of the iallocator interface.
2

    
3
-}
4

    
5
module Ganeti.HTools.IAlloc
6
    (
7
      parseData
8
    , formatResponse
9
    ) where
10

    
11
import Data.Either ()
12
import Data.Maybe
13
import Control.Monad
14
import Text.JSON
15
import Text.Printf (printf)
16
import Ganeti.HTools.Utils
17

    
18
data RqType
19
    = Allocate
20
    | Relocate
21
    deriving (Show)
22

    
23
parseInstance :: String -> JSObject JSValue -> Either String String
24
parseInstance n a =
25
    let name = Right n
26
        disk = case getIntElement "disk_usage" a of
27
                 Left _ -> let all_d = getListElement "disks" a `combineEithers`
28
                                       asObjectList
29
                               szd = all_d `combineEithers`
30
                                     (ensureEitherList .
31
                                      map (getIntElement "size"))
32
                               sze = applyEither1 (map (+128)) szd
33
                               szf = applyEither1 sum sze
34
                           in szf
35
                 Right x -> Right x
36
        nodes = getListElement "nodes" a
37
        pnode = eitherListHead nodes
38
                `combineEithers` readEitherString
39
        snode = applyEither1 (head . tail) nodes
40
                `combineEithers` readEitherString
41
        mem = getIntElement "memory" a
42
        running = Right "running" --getStringElement "status" a
43
    in
44
      concatEitherElems name $
45
                  concatEitherElems (show `applyEither1` mem) $
46
                  concatEitherElems (show `applyEither1` disk) $
47
                  concatEitherElems running $
48
                  concatEitherElems pnode snode
49

    
50
parseNode :: String -> JSObject JSValue -> Either String String
51
parseNode n a =
52
    let name = Right n
53
        mtotal = getIntElement "total_memory" a
54
        mnode = getIntElement "reserved_memory" a
55
        mfree = getIntElement "free_memory" a
56
        dtotal = getIntElement "total_disk" a
57
        dfree = getIntElement "free_disk" a
58
    in concatEitherElems name $
59
       concatEitherElems (show `applyEither1` mtotal) $
60
       concatEitherElems (show `applyEither1` mnode) $
61
       concatEitherElems (show `applyEither1` mfree) $
62
       concatEitherElems (show `applyEither1` dtotal)
63
                             (show `applyEither1` dfree)
64

    
65
validateRequest :: String -> Either String RqType
66
validateRequest rq =
67
    case rq of
68
      "allocate" -> Right Allocate
69
      "relocate" -> Right Relocate
70
      _ -> Left ("Invalid request type '" ++ rq ++ "'")
71

    
72
parseData :: String -> Either String (String, String)
73
parseData body =
74
    let
75
        decoded = resultToEither $ decodeStrict body
76
        obj = decoded -- decoded `combineEithers` fromJSObject
77
        -- request parser
78
        request = obj `combineEithers` getObjectElement "request"
79
        rname = request `combineEithers` getStringElement "name"
80
        rtype = request `combineEithers` getStringElement "type"
81
                `combineEithers` validateRequest
82
        -- existing intstance parsing
83
        ilist = obj `combineEithers` getObjectElement "instances"
84
        idata = applyEither1 fromJSObject ilist
85
        iobj = idata `combineEithers` (ensureEitherList .
86
                                       map (\(x,y) ->
87
                                           asJSObject y `combineEithers`
88
                                                      parseInstance x))
89
        ilines = iobj `combineEithers` (Right . unlines)
90
        -- existing node parsing
91
        nlist = obj `combineEithers` getObjectElement "nodes"
92
        ndata = applyEither1 fromJSObject nlist
93
        nobj = ndata `combineEithers` (ensureEitherList .
94
                                       map (\(x,y) ->
95
                                           asJSObject y `combineEithers`
96
                                                      parseNode x))
97
        nlines = nobj `combineEithers` (Right . unlines)
98
    in applyEither2 (,) nlines ilines
99

    
100
formatResponse :: Bool -> String -> [String] -> String
101
formatResponse success info nodes =
102
    let
103
        e_success = ("success", JSBool success)
104
        e_info = ("info", JSString . toJSString $ info)
105
        e_nodes = ("nodes", JSArray $ map (JSString . toJSString) nodes)
106
    in encodeStrict $ makeObj [e_success, e_info, e_nodes]