{-# LANGUAGE OverloadedStrings #-}
module PuppetDB.Rest where
import Puppet.Interpreter.Types
import Puppet.Printers
import Network.HTTP.Conduit
import qualified Network.HTTP.Types as W
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Char8 as BC
import qualified Data.Vector as V
import Data.Aeson
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
import Data.Attoparsec.Number
import qualified Codec.Text.IConv as IConv
instance FromJSON ResolvedValue where
parseJSON Null = return ResolvedUndefined
parseJSON (Number x) = return $ case x of
(I n) -> ResolvedInt n
(D d) -> ResolvedDouble d
parseJSON (String s) = return $ ResolvedString $ T.unpack s
parseJSON (Array a) = fmap ResolvedArray (mapM parseJSON (V.toList a))
parseJSON (Object o) = fmap ResolvedHash (mapM (\(a,b) -> do {
b' <- parseJSON b ;
return (T.unpack a,b') }
) (HM.toList o))
parseJSON (Bool b) = return $ ResolvedBool b
toAndQuery = undefined
simpleNodeQuery :: String -> [(String, String)] -> IO (Either String ResolvedValue)
simpleNodeQuery url query = rawRequest url "nodes" (toAndQuery query)
simpleResourceQuery :: String -> [(String, String)] -> IO (Either String ResolvedValue)
simpleResourceQuery url query = rawRequest url "resources" (toAndQuery query)
rawRequest :: String -> String -> String -> IO (Either String ResolvedValue)
rawRequest url querytype query = do
let q = BC.unpack $ W.renderSimpleQuery False [("query", BC.pack query)]
pfunc = parseUrl (url ++ "/" ++ querytype ++ "?" ++ q)
eInitReq <- case querytype of
"resources" -> fmap Right pfunc
"nodes" -> fmap Right pfunc
_ -> return $ Left $ "Invalid query type " ++ querytype
case eInitReq of
Right initReq -> do
let req = initReq { requestHeaders = [("Accept", "application/json")] }
o <- withManager (\manager -> fmap responseBody $ httpLbs req manager) :: IO L.ByteString
let utf8 = IConv.convert "LATIN1" "UTF-8" o
case decode' utf8 :: Maybe ResolvedValue of
Just x@(ResolvedArray _) -> return $ Right x
Just x -> return $ Left $ "PuppetDB should have returned an array, not " ++ showValue x
Nothing -> return $ Left "Json decoding has failed"
Left err -> return $ Left err