module Ganeti.Confd.Types
( C.confdProtocolVersion
, C.confdMaxClockSkew
, C.confdConfigReloadTimeout
, C.confdConfigReloadRatelimit
, C.confdMagicFourcc
, C.confdDefaultReqCoverage
, C.confdClientExpireTimeout
, C.maxUdpDataSize
, ConfdClient(..)
, ConfdRequestType(..)
, ConfdReqQ(..)
, ConfdReqField(..)
, ConfdReplyStatus(..)
, ConfdNodeRole(..)
, ConfdErrorType(..)
, ConfdRequest(..)
, newConfdRequest
, ConfdReply(..)
, ConfdQuery(..)
, SignedMessage(..)
) where
import Text.JSON
import qualified Network.Socket as S
import qualified Ganeti.Constants as C
import Ganeti.Hash
import Ganeti.THH
import Ganeti.Utils (newUUID)
$(declareIADT "ConfdRequestType"
[ ("ReqPing", 'C.confdReqPing )
, ("ReqNodeRoleByName", 'C.confdReqNodeRoleByname )
, ("ReqNodePipList", 'C.confdReqNodePipList )
, ("ReqNodePipByInstPip", 'C.confdReqNodePipByInstanceIp )
, ("ReqClusterMaster", 'C.confdReqClusterMaster )
, ("ReqMcPipList", 'C.confdReqMcPipList )
, ("ReqInstIpsList", 'C.confdReqInstancesIpsList )
, ("ReqNodeDrbd", 'C.confdReqNodeDrbd )
, ("ReqNodeInstances", 'C.confdReqNodeInstances)
])
$(makeJSONInstance ''ConfdRequestType)
$(declareSADT "ConfdReqField"
[ ("ReqFieldName", 'C.confdReqfieldName )
, ("ReqFieldIp", 'C.confdReqfieldIp )
, ("ReqFieldMNodePip", 'C.confdReqfieldMnodePip )
])
$(makeJSONInstance ''ConfdReqField)
$(buildObject "ConfdReqQ" "confdReqQ"
[ renameField "Ip" .
optionalField $ simpleField C.confdReqqIp [t| String |]
, renameField "IpList" .
defaultField [| [] |] $
simpleField C.confdReqqIplist [t| [String] |]
, renameField "Link" . optionalField $
simpleField C.confdReqqLink [t| String |]
, renameField "Fields" . defaultField [| [] |] $
simpleField C.confdReqqFields [t| [ConfdReqField] |]
])
data ConfdQuery = EmptyQuery
| PlainQuery String
| DictQuery ConfdReqQ
deriving (Show, Eq)
instance JSON ConfdQuery where
readJSON o = case o of
JSNull -> return EmptyQuery
JSString s -> return . PlainQuery . fromJSString $ s
JSObject _ -> fmap DictQuery (readJSON o::Result ConfdReqQ)
_ -> fail $ "Cannot deserialise into ConfdQuery\
\ the value '" ++ show o ++ "'"
showJSON cq = case cq of
EmptyQuery -> JSNull
PlainQuery s -> showJSON s
DictQuery drq -> showJSON drq
$(declareIADT "ConfdReplyStatus"
[ ( "ReplyStatusOk", 'C.confdReplStatusOk )
, ( "ReplyStatusError", 'C.confdReplStatusError )
, ( "ReplyStatusNotImpl", 'C.confdReplStatusNotimplemented )
])
$(makeJSONInstance ''ConfdReplyStatus)
$(declareIADT "ConfdNodeRole"
[ ( "NodeRoleMaster", 'C.confdNodeRoleMaster )
, ( "NodeRoleCandidate", 'C.confdNodeRoleCandidate )
, ( "NodeRoleOffline", 'C.confdNodeRoleOffline )
, ( "NodeRoleDrained", 'C.confdNodeRoleDrained )
, ( "NodeRoleRegular", 'C.confdNodeRoleRegular )
])
$(makeJSONInstance ''ConfdNodeRole)
$(declareIADT "ConfdErrorType"
[ ( "ConfdErrorUnknownEntry", 'C.confdErrorUnknownEntry )
, ( "ConfdErrorInternal", 'C.confdErrorInternal )
, ( "ConfdErrorArgument", 'C.confdErrorArgument )
])
$(makeJSONInstance ''ConfdErrorType)
$(buildObject "ConfdRequest" "confdRq"
[ simpleField "protocol" [t| Int |]
, simpleField "type" [t| ConfdRequestType |]
, defaultField [| EmptyQuery |] $ simpleField "query" [t| ConfdQuery |]
, simpleField "rsalt" [t| String |]
])
newConfdRequest :: ConfdRequestType -> ConfdQuery -> IO ConfdRequest
newConfdRequest reqType query = do
rsalt <- newUUID
return $ ConfdRequest C.confdProtocolVersion reqType query rsalt
$(buildObject "ConfdReply" "confdReply"
[ simpleField "protocol" [t| Int |]
, simpleField "status" [t| ConfdReplyStatus |]
, simpleField "answer" [t| JSValue |]
, simpleField "serial" [t| Int |]
])
$(buildObject "SignedMessage" "signedMsg"
[ simpleField "hmac" [t| String |]
, simpleField "msg" [t| String |]
, simpleField "salt" [t| String |]
])
data ConfdClient = ConfdClient
{ hmacKey :: HashKey
, peers :: [String]
, serverPort :: S.PortNumber
}