module PuppetDB.TestDB (initTestDBFunctions) where
import PuppetDB.Query
import Puppet.Interpreter.Types
import Puppet.DSL.Types hiding (Value)
import Data.Aeson
import qualified Data.Map as Map
import Control.Concurrent.MVar
import qualified Data.Text as T
type ExportedResources = Map.Map T.Text (FinalCatalog, EdgeMap, FinalCatalog)
initTestDBFunctions :: (T.Text -> Query -> IO (Either String Value)) -> IO (T.Text -> Query -> IO (Either String Value), T.Text -> (FinalCatalog, EdgeMap, FinalCatalog) -> IO ())
initTestDBFunctions defaultquery = do
v <- newMVar Map.empty
return (queryPDB v defaultquery, updatePDB v)
updatePDB :: MVar ExportedResources -> T.Text -> (FinalCatalog, EdgeMap, FinalCatalog) -> IO ()
updatePDB v node res = do
ex <- takeMVar v
let ex' = Map.insert node res ex
putMVar v ex'
toBool :: T.Text -> Either String Bool
toBool "true" = Right True
toBool "false" = Right False
toBool x = Left ("Is not a boolean " ++ T.unpack x)
evaluateQueryResource :: Query -> Bool -> T.Text -> ResIdentifier -> RResource -> Either String Bool
evaluateQueryResource (Query OAnd lst) e n rid rr = fmap and (mapM (\x -> evaluateQueryResource x e n rid rr) lst)
evaluateQueryResource (Query OOr lst) e n rid rr = fmap or (mapM (\x -> evaluateQueryResource x e n rid rr) lst)
evaluateQueryResource (Query OEqual [Terms ["node","active"], Term bool]) _ _ _ _ = toBool bool
evaluateQueryResource (Query OEqual [Terms ["node","name"], Term hname]) _ n _ _ = Right (n == hname)
evaluateQueryResource (Query OEqual [Term "type",Term ctype]) _ _ _ rr = Right (capitalizeResType (rrtype rr) == ctype)
evaluateQueryResource (Query OEqual [Term "exported",Term expo]) exported _ _ _ = toBool expo >>= \x -> return (x == exported)
evaluateQueryResource (Query OEqual [Term "tag",Term tag]) _ _ _ rr =
let tags = Map.findWithDefault (ResolvedArray []) "tag" (rrparams rr)
stringEqual y (ResolvedString x) = (x == y)
stringEqual _ _ = False
in case tags of
ResolvedArray lst -> Right (any (stringEqual tag) lst)
_ -> Right (stringEqual tag tags)
evaluateQueryResource (Query OEqual [Term "title", Term ttl]) _ _ _ rr = Right (rrname rr == ttl)
evaluateQueryResource (Query ONot [q]) e n rid rr = fmap not (evaluateQueryResource q e n rid rr)
evaluateQueryResource q _ _ _ _ = Left ("Not interpreted: " ++ show q)
queryPDB :: MVar ExportedResources -> (T.Text -> Query -> IO (Either String Value)) -> T.Text -> Query -> IO (Either String Value)
queryPDB v _ "resources" query = do
ex <- readMVar v
let isSelected = evaluateQueryResource query
sortResources :: Either String ([(T.Text,ResIdentifier,RResource)], [(T.Text,ResIdentifier,RResource)])
-> T.Text
-> (FinalCatalog, EdgeMap, FinalCatalog)
-> Either String ([(T.Text,ResIdentifier,RResource)], [(T.Text,ResIdentifier,RResource)])
sortResources (Left rr) _ _ = Left rr
sortResources (Right (curnormal, curexported)) nodename (fnormal, _, fexported) =
let newnormal = Map.foldlWithKey' (sortResources' False nodename) (Right curnormal ) fnormal
newexported = Map.foldlWithKey' (sortResources' True nodename) (Right curexported) fexported
in case (newnormal, newexported) of
(Left r1, _) -> Left r1
(_, Left r2) -> Left r2
(Right n, Right e) -> Right (n,e)
sortResources' :: Bool -> T.Text -> Either String [(T.Text,ResIdentifier,RResource)] -> ResIdentifier -> RResource -> Either String [(T.Text,ResIdentifier,RResource)]
sortResources' _ _ (Left rr) _ _ = Left rr
sortResources' e nodename (Right curlist) resid rr = case isSelected e nodename resid rr of
Right False -> Right curlist
Right True -> Right ((nodename,resid,rr) : curlist)
Left err -> Left err
jsonize :: (T.Text,ResIdentifier,RResource) -> Value
jsonize (h,_,r) = rr2json h r
case Map.foldlWithKey' sortResources (Right ([], [])) ex of
Right (n,e) -> return $ Right $ toJSON $ map jsonize ( n ++ e )
Left rr -> return (Left rr)
queryPDB _ _ querytype query = error (show (querytype, query))