, RpcCallVersion(..)
, RpcResultVersion(..)
- , StorageType(..)
, StorageField(..)
, RpcCallStorageList(..)
, RpcResultStorageList(..)
+ , RpcCallTestDelay(..)
+ , RpcResultTestDelay(..)
+
, rpcTimeoutFromRaw -- FIXME: Not used anywhere
) where
import Control.Arrow (second)
import qualified Text.JSON as J
import Text.JSON.Pretty (pp_value)
-import Text.JSON (makeObj)
#ifndef NO_CURL
import Network.Curl
import qualified Ganeti.Constants as C
import Ganeti.Objects
import Ganeti.THH
+import Ganeti.Types
import Ganeti.Compat
-import Ganeti.JSON
+
+-- * Base RPC functionality and types
#ifndef NO_CURL
-- | The curl options used for RPC.
curlOpts :: [CurlOption]
curlOpts = [ CurlFollowLocation False
- , CurlCAInfo P.nodedCertFile
, CurlSSLVerifyHost 0
, CurlSSLVerifyPeer True
, CurlSSLCertType "PEM"
- , CurlSSLCert P.nodedCertFile
, CurlSSLKeyType "PEM"
- , CurlSSLKey P.nodedCertFile
, CurlConnectTimeout (fromIntegral C.rpcConnectTimeout)
]
#endif
executeHttpRequest _ _ = return $ Left CurlDisabledError
#else
executeHttpRequest node (Right request) = do
+ cert_file <- P.nodedCertFile
let reqOpts = [ CurlTimeout (fromIntegral $ requestTimeout request)
, CurlPostFields [requestPostData request]
+ , CurlSSLCert cert_file
+ , CurlSSLKey cert_file
+ , CurlCAInfo cert_file
]
url = requestUrl request
-- FIXME: This is very similar to getUrl in Htools/Rapi.hs
-- | Helper function that is used to read dictionaries of values.
sanitizeDictResults :: [(String, J.Result a)] -> ERpcError [(String, a)]
-sanitizeDictResults [] = Right []
-sanitizeDictResults ((_, J.Error err):_) = Left $ JsonDecodeError err
-sanitizeDictResults ((name, J.Ok val):xs) =
- case sanitizeDictResults xs of
- Left err -> Left err
- Right res' -> Right $ (name, val):res'
+sanitizeDictResults =
+ foldr sanitize1 (Right [])
+ where
+ sanitize1 _ (Left e) = Left e
+ sanitize1 (_, J.Error e) _ = Left $ JsonDecodeError e
+ sanitize1 (name, J.Ok v) (Right res) = Right $ (name, v) : res
-- | Helper function to tranform JSON Result to Either RpcError b.
-- Note: For now we really only use it for b s.t. Rpc c b for some c
-- * RPC calls and results
+-- ** Instance info
+
-- | InstanceInfo
-- Returns information about a single instance.
_ -> Left $ JsonDecodeError
("Expected JSObject, got " ++ show (pp_value res))
+-- ** AllInstancesInfo
+
-- | AllInstancesInfo
-- Returns information about all running instances on the given nodes
$(buildObject "RpcCallAllInstancesInfo" "rpcCallAllInstInfo"
_ -> Left $ JsonDecodeError
("Expected JSObject, got " ++ show (pp_value res))
+-- ** InstanceList
+
-- | InstanceList
-- Returns the list of running instances on the given nodes.
$(buildObject "RpcCallInstanceList" "rpcCallInstList"
instance Rpc RpcCallInstanceList RpcResultInstanceList where
rpcResultFill _ res = fromJSValueToRes res RpcResultInstanceList
+-- ** NodeInfo
+
-- | NodeInfo
-- Return node information.
$(buildObject "RpcCallNodeInfo" "rpcCallNodeInfo"
rpcResultFill _ res =
fromJSValueToRes res (\(b, vg, hv) -> RpcResultNodeInfo b vg hv)
+-- ** Version
+
-- | Version
-- Query node version.
-- Note: We can't use THH as it does not know what to do with empty dict
data RpcCallVersion = RpcCallVersion {}
- deriving (Show, Read, Eq)
+ deriving (Show, Eq)
instance J.JSON RpcCallVersion where
showJSON _ = J.JSNull
rpcCallName _ = "version"
rpcCallTimeout _ = rpcTimeoutToRaw Urgent
rpcCallAcceptOffline _ = True
- rpcCallData call _ = J.encode [call]
+ rpcCallData _ = J.encode
instance Rpc RpcCallVersion RpcResultVersion where
rpcResultFill _ res = fromJSValueToRes res RpcResultVersion
+-- ** StorageList
+
-- | StorageList
--- Get list of storage units.
--- FIXME: This may be moved to Objects
-$(declareSADT "StorageType"
- [ ( "STLvmPv", 'C.stLvmPv )
- , ( "STFile", 'C.stFile )
- , ( "STLvmVg", 'C.stLvmVg )
- ])
-$(makeJSONInstance ''StorageType)
-- FIXME: This may be moved to Objects
$(declareSADT "StorageField"
rpcResultFill call res =
let sfields = rpcCallStorageListFields call in
fromJSValueToRes res (RpcResultStorageList . map (zip sfields))
+
+-- ** TestDelay
+
+
+-- | Call definition for test delay.
+$(buildObject "RpcCallTestDelay" "rpcCallTestDelay"
+ [ simpleField "duration" [t| Double |]
+ ])
+
+-- | Result definition for test delay.
+data RpcResultTestDelay = RpcResultTestDelay
+ deriving Show
+
+-- | Custom JSON instance for null result.
+instance J.JSON RpcResultTestDelay where
+ showJSON _ = J.JSNull
+ readJSON J.JSNull = return RpcResultTestDelay
+ readJSON _ = fail "Unable to read RpcResultTestDelay"
+
+instance RpcCall RpcCallTestDelay where
+ rpcCallName _ = "test_delay"
+ rpcCallTimeout = ceiling . (+ 5) . rpcCallTestDelayDuration
+ rpcCallAcceptOffline _ = False
+ rpcCallData _ call = J.encode [rpcCallTestDelayDuration call]
+
+instance Rpc RpcCallTestDelay RpcResultTestDelay where
+ rpcResultFill _ res = fromJSValueToRes res id