Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Rapi.hs @ 9ba5c28f

History | View | Annotate | Download (3.5 kB)

1
{-| Implementation of the RAPI client interface.
2

    
3
-}
4

    
5
module Ganeti.HTools.Rapi
6
    (
7
      getNodes
8
    , getInstances
9
    ) where
10

    
11
import Network.Curl
12
import Network.Curl.Types ()
13
import Network.Curl.Code
14
import Data.Either ()
15
import Data.Maybe
16
import Control.Monad
17
import Text.JSON
18
import Text.Printf (printf)
19
import Ganeti.HTools.Utils
20

    
21

    
22
-- Some constants
23

    
24
-- | The fixed drbd overhead per disk (only used with 1.2's sdx_size)
25
drbdOverhead = 128
26

    
27
getUrl :: String -> IO (Either String String)
28
getUrl url = do
29
  (code, body) <- curlGetString url [CurlSSLVerifyPeer False,
30
                                     CurlSSLVerifyHost 0]
31
  return (case code of
32
            CurlOK -> Right body
33
            _ -> Left $ printf "Curl error for '%s', error %s"
34
                 url (show code))
35

    
36
tryRapi :: String -> String -> IO (Either String String)
37
tryRapi url1 url2 =
38
    do
39
      body1 <- getUrl url1
40
      (case body1 of
41
         Left _ -> getUrl url2
42
         Right _ -> return body1)
43

    
44
getInstances :: String -> IO (Either String String)
45
getInstances master =
46
    let
47
        url2 = printf "https://%s:5080/2/instances?bulk=1" master
48
        url1 = printf "http://%s:5080/instances?bulk=1" master
49
    in do
50
      body <- tryRapi url1 url2
51
      let inst = body `combineEithers`
52
                 loadJSArray `combineEithers`
53
                 (parseEitherList parseInstance)
54
      return inst
55

    
56
getNodes :: String -> IO (Either String String)
57
getNodes master =
58
    let
59
        url2 = printf "https://%s:5080/2/nodes?bulk=1" master
60
        url1 = printf "http://%s:5080/nodes?bulk=1" master
61
    in do
62
      body <- tryRapi url1 url2
63
      let inst = body `combineEithers`
64
                 loadJSArray `combineEithers`
65
                 (parseEitherList parseNode)
66
      return inst
67

    
68
parseInstance :: JSObject JSValue -> Either String String
69
parseInstance a =
70
    let name = getStringElement "name" a
71
        disk = case getIntElement "disk_usage" a of
72
                 Left _ -> let log_sz = applyEither2 (+)
73
                                        (getIntElement "sda_size" a)
74
                                        (getIntElement "sdb_size" a)
75
                           in applyEither2 (+) log_sz
76
                                  (Right $ drbdOverhead * 2)
77
                 Right x -> Right x
78
        bep = fromObj "beparams" a
79
        pnode = getStringElement "pnode" a
80
        snode = (eitherListHead $ getListElement "snodes" a)
81
                `combineEithers` readEitherString
82
        mem = case bep of
83
                Left _ -> getIntElement "admin_ram" a
84
                Right o -> getIntElement "memory" o
85
        running = getStringElement "status" a
86
    in
87
      concatEitherElems name $
88
                  concatEitherElems (show `applyEither1` mem) $
89
                  concatEitherElems (show `applyEither1` disk) $
90
                  concatEitherElems running $
91
                  concatEitherElems pnode snode
92

    
93
parseNode :: JSObject JSValue -> Either String String
94
parseNode a =
95
    let name = getStringElement "name" a
96
        mtotal = getIntElement "mtotal" a
97
        mnode = getIntElement "mnode" a
98
        mfree = getIntElement "mfree" a
99
        dtotal = getIntElement "dtotal" a
100
        dfree = getIntElement "dfree" a
101
    in concatEitherElems name $
102
       concatEitherElems (show `applyEither1` mtotal) $
103
       concatEitherElems (show `applyEither1` mnode) $
104
       concatEitherElems (show `applyEither1` mfree) $
105
       concatEitherElems (show `applyEither1` dtotal)
106
                             (show `applyEither1` dfree)