Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Rapi.hs @ e015b554

History | View | Annotate | Download (2.8 kB)

1 a7654563 Iustin Pop
{-| Implementation of the RAPI client interface.
2 a7654563 Iustin Pop
3 a7654563 Iustin Pop
-}
4 a7654563 Iustin Pop
5 669d7e3d Iustin Pop
module Ganeti.HTools.Rapi
6 dd4c56ed Iustin Pop
    (
7 dd4c56ed Iustin Pop
      getNodes
8 dd4c56ed Iustin Pop
    , getInstances
9 dd4c56ed Iustin Pop
    ) where
10 a7654563 Iustin Pop
11 a7654563 Iustin Pop
import Network.Curl
12 b8b9a53c Iustin Pop
import Network.Curl.Types ()
13 a7654563 Iustin Pop
import Network.Curl.Code
14 b8b9a53c Iustin Pop
import Data.Either ()
15 aab26f2d Iustin Pop
import Data.Maybe
16 e015b554 Iustin Pop
import Data.List
17 a7654563 Iustin Pop
import Control.Monad
18 942403e6 Iustin Pop
import Text.JSON (JSObject, JSValue)
19 a7654563 Iustin Pop
import Text.Printf (printf)
20 9ba5c28f Iustin Pop
import Ganeti.HTools.Utils
21 a7654563 Iustin Pop
22 ba00ad4d Iustin Pop
-- | Read an URL via curl and return the body if successful
23 ba00ad4d Iustin Pop
getUrl :: (Monad m) => String -> IO (m String)
24 a7654563 Iustin Pop
getUrl url = do
25 a7654563 Iustin Pop
  (code, body) <- curlGetString url [CurlSSLVerifyPeer False,
26 a7654563 Iustin Pop
                                     CurlSSLVerifyHost 0]
27 a7654563 Iustin Pop
  return (case code of
28 ba00ad4d Iustin Pop
            CurlOK -> return body
29 ba00ad4d Iustin Pop
            _ -> fail $ printf "Curl error for '%s', error %s"
30 aab26f2d Iustin Pop
                 url (show code))
31 aab26f2d Iustin Pop
32 e015b554 Iustin Pop
-- | Append the default port if not passed in
33 e015b554 Iustin Pop
formatHost :: String -> String
34 e015b554 Iustin Pop
formatHost master =
35 e015b554 Iustin Pop
    if elem ':' master then  master
36 e015b554 Iustin Pop
    else "https://" ++ master ++ ":5080"
37 e015b554 Iustin Pop
38 942403e6 Iustin Pop
getInstances :: String -> IO (Result String)
39 aff363a4 Iustin Pop
getInstances master = do
40 e015b554 Iustin Pop
  let url2 = printf "%s/2/instances?bulk=1" (formatHost master)
41 aff363a4 Iustin Pop
  body <- getUrl url2
42 942403e6 Iustin Pop
  return $ (body >>= \x -> do
43 942403e6 Iustin Pop
              arr <- loadJSArray x
44 942403e6 Iustin Pop
              ilist <- mapM parseInstance arr
45 942403e6 Iustin Pop
              return $ unlines ilist)
46 a7654563 Iustin Pop
47 942403e6 Iustin Pop
getNodes :: String -> IO (Result String)
48 aff363a4 Iustin Pop
getNodes master = do
49 e015b554 Iustin Pop
  let url2 = printf "%s/2/nodes?bulk=1" (formatHost master)
50 aff363a4 Iustin Pop
  body <- getUrl url2
51 942403e6 Iustin Pop
  return $ (body >>= \x -> do
52 942403e6 Iustin Pop
             arr <- loadJSArray x
53 942403e6 Iustin Pop
             nlist <- mapM parseNode arr
54 942403e6 Iustin Pop
             return $ unlines nlist)
55 a7654563 Iustin Pop
56 942403e6 Iustin Pop
parseInstance :: JSObject JSValue -> Result String
57 a7654563 Iustin Pop
parseInstance a =
58 a7654563 Iustin Pop
    let name = getStringElement "name" a
59 ba00ad4d Iustin Pop
        disk = getIntElement "disk_usage" a
60 ba00ad4d Iustin Pop
        mem = getObjectElement "beparams" a >>= getIntElement "memory"
61 b8b9a53c Iustin Pop
        pnode = getStringElement "pnode" a
62 ba00ad4d Iustin Pop
        snode = (liftM head $ getListElement "snodes" a) >>= readEitherString
63 f82f1f39 Iustin Pop
        running = getStringElement "status" a
64 a7654563 Iustin Pop
    in
65 942403e6 Iustin Pop
      name |+ (show `liftM` mem) |+
66 942403e6 Iustin Pop
              (show `liftM` disk) |+
67 942403e6 Iustin Pop
              running |+ pnode |+ snode
68 a7654563 Iustin Pop
69 5aa48dbe Iustin Pop
boolToYN :: (Monad m) => Bool -> m String
70 5aa48dbe Iustin Pop
boolToYN True = return "Y"
71 5aa48dbe Iustin Pop
boolToYN _ = return "N"
72 00b15752 Iustin Pop
73 942403e6 Iustin Pop
parseNode :: JSObject JSValue -> Result String
74 a7654563 Iustin Pop
parseNode a =
75 a7654563 Iustin Pop
    let name = getStringElement "name" a
76 00b15752 Iustin Pop
        offline = getBoolElement "offline" a
77 00b15752 Iustin Pop
        drained = getBoolElement "drained" a
78 a7654563 Iustin Pop
        mtotal = getIntElement "mtotal" a
79 04be800a Iustin Pop
        mnode = getIntElement "mnode" a
80 a7654563 Iustin Pop
        mfree = getIntElement "mfree" a
81 a7654563 Iustin Pop
        dtotal = getIntElement "dtotal" a
82 a7654563 Iustin Pop
        dfree = getIntElement "dfree" a
83 942403e6 Iustin Pop
    in name |+
84 00b15752 Iustin Pop
       (case offline of
85 942403e6 Iustin Pop
          Ok True -> Ok "0|0|0|0|0|Y"
86 00b15752 Iustin Pop
          _ ->
87 942403e6 Iustin Pop
              (show `liftM` mtotal) |+ (show `liftM` mnode) |+
88 942403e6 Iustin Pop
              (show `liftM` mfree) |+ (show `liftM` dtotal) |+
89 942403e6 Iustin Pop
              (show `liftM` dfree) |+
90 942403e6 Iustin Pop
              ((liftM2 (||) offline drained) >>= boolToYN)
91 00b15752 Iustin Pop
       )