    {-# LANGUAGE PackageImports #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE DataKinds #-}

    module Propellor.PrivData (
    	withPrivData,
    	withSomePrivData,
    	addPrivData,
    	setPrivData,
    	unsetPrivData,
    	unsetPrivDataUnused,
    	dumpPrivData,
    	editPrivData,
    	filterPrivData,
    	listPrivDataFields,
    	makePrivDataDir,
    	decryptPrivData,
    	readPrivData,
    	readPrivDataFile,
    	PrivMap,
    	PrivInfo,
    	forceHostContext,
    ) where

    import System.IO
    import Data.Maybe
    import Data.List
    import Data.Typeable
    import Control.Monad
    import Control.Monad.IfElse
    import "mtl" Control.Monad.Reader
    import qualified Data.Map as M
    import qualified Data.Set as S
    import qualified Data.ByteString.Lazy as L
    import Control.Applicative
    import Data.Monoid
    import Data.Semigroup as Sem
    import Prelude

    import Propellor.Types
    import Propellor.Types.PrivData
    import Propellor.Types.MetaTypes
    import Propellor.Types.Info
    import Propellor.Message
    import Propellor.Info
    import Propellor.Gpg
    import Propellor.PrivData.Paths
    import Utility.Monad
    import Utility.PartialPrelude
    import Utility.Exception
    import Utility.Tmp
    import Utility.SafeCommand
    import Utility.Process.NonConcurrent
    import Utility.Misc
    import Utility.FileMode
    import Utility.Env
    import Utility.Table
    import Utility.Directory

    -- | Allows a Property to access the value of a specific PrivDataField,
    -- for use in a specific Context or HostContext.
    --
    -- Example use:
    --
    -- > withPrivData (PrivFile pemfile) (Context "joeyh.name") $ \getdata ->
    -- >     property "joeyh.name ssl cert" $ getdata $ \privdata ->
    -- >       liftIO $ writeFile pemfile (privDataVal privdata)
    -- >   where pemfile = "/etc/ssl/certs/web.pem"
    --
    -- Note that if the value is not available, the action is not run
    -- and instead it prints a message to help the user make the necessary
    -- private data available.
    --
    -- The resulting Property includes Info about the PrivDataField
    -- being used, which is necessary to ensure that the privdata is sent to
    -- the remote host by propellor.
    withPrivData
    	::
    		( IsContext c
    		, IsPrivDataSource s
    		, IncludesInfo metatypes ~ 'True
    		)
    	=> s
    	-> c
    	-> (((PrivData -> Propellor Result) -> Propellor Result) -> Property metatypes)
    	-> Property metatypes
    withPrivData :: forall c s metatypes.
    (IsContext c, IsPrivDataSource s,
     IncludesInfo metatypes ~ 'True) =>
    s
    -> c
    -> (((PrivData -> Propellor Result) -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    withPrivData s
    s = ((PrivDataField, PrivData) -> PrivData)
    -> [s]
    -> c
    -> (((PrivData -> Propellor Result) -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    forall c s metatypes v.
    (IsContext c, IsPrivDataSource s,
     IncludesInfo metatypes ~ 'True) =>
    ((PrivDataField, PrivData) -> v)
    -> [s]
    -> c
    -> (((v -> Propellor Result) -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    withPrivData' (PrivDataField, PrivData) -> PrivData
    forall a b. (a, b) -> b
    snd [s
    s]

    -- Like withPrivData, but here any one of a list of PrivDataFields can be used.
    withSomePrivData
    	::
    		( IsContext c
    		, IsPrivDataSource s
    		, IncludesInfo metatypes ~ 'True
    		)
    	=> [s]
    	-> c
    	-> ((((PrivDataField, PrivData) -> Propellor Result) -> Propellor Result) -> Property metatypes)
    	-> Property metatypes
    withSomePrivData :: forall c s metatypes.
    (IsContext c, IsPrivDataSource s,
     IncludesInfo metatypes ~ 'True) =>
    [s]
    -> c
    -> ((((PrivDataField, PrivData) -> Propellor Result)
         -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    withSomePrivData = ((PrivDataField, PrivData) -> (PrivDataField, PrivData))
    -> [s]
    -> c
    -> ((((PrivDataField, PrivData) -> Propellor Result)
         -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    forall c s metatypes v.
    (IsContext c, IsPrivDataSource s,
     IncludesInfo metatypes ~ 'True) =>
    ((PrivDataField, PrivData) -> v)
    -> [s]
    -> c
    -> (((v -> Propellor Result) -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    withPrivData' (PrivDataField, PrivData) -> (PrivDataField, PrivData)
    forall a. a -> a
    id

    withPrivData'
    	::
    		( IsContext c
    		, IsPrivDataSource s
    		, IncludesInfo metatypes ~ 'True
    		)
    	=> ((PrivDataField, PrivData) -> v)
    	-> [s]
    	-> c
    	-> (((v -> Propellor Result) -> Propellor Result) -> Property metatypes)
    	-> Property metatypes
    withPrivData' :: forall c s metatypes v.
    (IsContext c, IsPrivDataSource s,
     IncludesInfo metatypes ~ 'True) =>
    ((PrivDataField, PrivData) -> v)
    -> [s]
    -> c
    -> (((v -> Propellor Result) -> Propellor Result)
        -> Property metatypes)
    -> Property metatypes
    withPrivData' (PrivDataField, PrivData) -> v
    feed [s]
    srclist c
    c ((v -> Propellor Result) -> Propellor Result) -> Property metatypes
    mkprop = Property metatypes -> Property metatypes
    addinfo (Property metatypes -> Property metatypes)
    -> Property metatypes -> Property metatypes
    forall a b. (a -> b) -> a -> b
    $ ((v -> Propellor Result) -> Propellor Result) -> Property metatypes
    mkprop (((v -> Propellor Result) -> Propellor Result)
     -> Property metatypes)
    -> ((v -> Propellor Result) -> Propellor Result)
    -> Property metatypes
    forall a b. (a -> b) -> a -> b
    $ \v -> Propellor Result
    a ->
    	Propellor Result
    -> ((PrivDataField, PrivData) -> Propellor Result)
    -> Maybe (PrivDataField, PrivData)
    -> Propellor Result
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Propellor Result
    missing (v -> Propellor Result
    a (v -> Propellor Result)
    -> ((PrivDataField, PrivData) -> v)
    -> (PrivDataField, PrivData)
    -> Propellor Result
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PrivDataField, PrivData) -> v
    feed) (Maybe (PrivDataField, PrivData) -> Propellor Result)
    -> Propellor (Maybe (PrivDataField, PrivData)) -> Propellor Result
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< (PrivDataField -> Propellor (Maybe (PrivDataField, PrivData)))
    -> [PrivDataField] -> Propellor (Maybe (PrivDataField, PrivData))
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m (Maybe b)) -> [a] -> m (Maybe b)
    getM PrivDataField -> Propellor (Maybe (PrivDataField, PrivData))
    get [PrivDataField]
    fieldlist
      where
      	get :: PrivDataField -> Propellor (Maybe (PrivDataField, PrivData))
    get PrivDataField
    field = do
    		context <- HostContext -> PrivDataSourceDesc -> Context
    mkHostContext HostContext
    hc (PrivDataSourceDesc -> Context)
    -> Propellor PrivDataSourceDesc -> Propellor Context
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Host -> PrivDataSourceDesc) -> Propellor PrivDataSourceDesc
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks Host -> PrivDataSourceDesc
    hostName
    		maybe Nothing (\PrivData
    privdata -> (PrivDataField, PrivData) -> Maybe (PrivDataField, PrivData)
    forall a. a -> Maybe a
    Just (PrivDataField
    field, PrivData
    privdata))
    			<$> liftIO (getLocalPrivData field context)
    	missing :: Propellor Result
    missing = do
    		Context cname <- HostContext -> PrivDataSourceDesc -> Context
    mkHostContext HostContext
    hc (PrivDataSourceDesc -> Context)
    -> Propellor PrivDataSourceDesc -> Propellor Context
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Host -> PrivDataSourceDesc) -> Propellor PrivDataSourceDesc
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks Host -> PrivDataSourceDesc
    hostName
    		warningMessage $ "Missing privdata " ++ intercalate " or " fieldnames ++ " (for " ++ cname ++ ")"
    		infoMessage $
    			"Fix this by running:" :
    			showSet (map (\s
    s -> (s -> PrivDataField
    forall s. IsPrivDataSource s => s -> PrivDataField
    privDataField s
    s, PrivDataSourceDesc -> Context
    Context PrivDataSourceDesc
    cname, s -> Maybe PrivDataSourceDesc
    forall s. IsPrivDataSource s => s -> Maybe PrivDataSourceDesc
    describePrivDataSource s
    s)) srclist)
    		return FailedChange
    	addinfo :: Property metatypes -> Property metatypes
    addinfo Property metatypes
    p = Property metatypes
    p Property metatypes -> Info -> Property metatypes
    forall metatypes.
    (IncludesInfo metatypes ~ 'True) =>
    Property metatypes -> Info -> Property metatypes
    `addInfoProperty` (PrivInfo -> Info
    forall v. IsInfo v => v -> Info
    toInfo PrivInfo
    privset)
    	privset :: PrivInfo
    privset = Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> PrivInfo
    PrivInfo (Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> PrivInfo)
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> PrivInfo
    forall a b. (a -> b) -> a -> b
    $ [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    forall a. Ord a => [a] -> Set a
    S.fromList ([(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
     -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext))
    -> [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    forall a b. (a -> b) -> a -> b
    $
    		(s -> (PrivDataField, Maybe PrivDataSourceDesc, HostContext))
    -> [s] -> [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\s
    s -> (s -> PrivDataField
    forall s. IsPrivDataSource s => s -> PrivDataField
    privDataField s
    s, s -> Maybe PrivDataSourceDesc
    forall s. IsPrivDataSource s => s -> Maybe PrivDataSourceDesc
    describePrivDataSource s
    s, HostContext
    hc)) [s]
    srclist
    	fieldnames :: [PrivDataSourceDesc]
    fieldnames = (PrivDataField -> PrivDataSourceDesc)
    -> [PrivDataField] -> [PrivDataSourceDesc]
    forall a b. (a -> b) -> [a] -> [b]
    map PrivDataField -> PrivDataSourceDesc
    forall a. Show a => a -> PrivDataSourceDesc
    show [PrivDataField]
    fieldlist
    	fieldlist :: [PrivDataField]
    fieldlist = (s -> PrivDataField) -> [s] -> [PrivDataField]
    forall a b. (a -> b) -> [a] -> [b]
    map s -> PrivDataField
    forall s. IsPrivDataSource s => s -> PrivDataField
    privDataField [s]
    srclist
    	hc :: HostContext
    hc = c -> HostContext
    forall c. IsContext c => c -> HostContext
    asHostContext c
    c

    showSet :: [(PrivDataField, Context, Maybe PrivDataSourceDesc)] -> [String]
    showSet :: [(PrivDataField, Context, Maybe PrivDataSourceDesc)]
    -> [PrivDataSourceDesc]
    showSet = ((PrivDataField, Context, Maybe PrivDataSourceDesc)
     -> [PrivDataSourceDesc])
    -> [(PrivDataField, Context, Maybe PrivDataSourceDesc)]
    -> [PrivDataSourceDesc]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (PrivDataField, Context, Maybe PrivDataSourceDesc)
    -> [PrivDataSourceDesc]
    forall {a}.
    Show a =>
    (a, Context, Maybe PrivDataSourceDesc) -> [PrivDataSourceDesc]
    go
      where
    	go :: (a, Context, Maybe PrivDataSourceDesc) -> [PrivDataSourceDesc]
    go (a
    f, Context PrivDataSourceDesc
    c, Maybe PrivDataSourceDesc
    md) = [Maybe PrivDataSourceDesc] -> [PrivDataSourceDesc]
    forall a. [Maybe a] -> [a]
    catMaybes
    		[ PrivDataSourceDesc -> Maybe PrivDataSourceDesc
    forall a. a -> Maybe a
    Just (PrivDataSourceDesc -> Maybe PrivDataSourceDesc)
    -> PrivDataSourceDesc -> Maybe PrivDataSourceDesc
    forall a b. (a -> b) -> a -> b
    $ PrivDataSourceDesc
    "  propellor --set '" PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ a -> PrivDataSourceDesc
    forall a. Show a => a -> PrivDataSourceDesc
    show a
    f PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataSourceDesc
    "' '" PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataSourceDesc
    c PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataSourceDesc
    "' \\"
    		, Maybe PrivDataSourceDesc
    -> (PrivDataSourceDesc -> Maybe PrivDataSourceDesc)
    -> Maybe PrivDataSourceDesc
    -> Maybe PrivDataSourceDesc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Maybe PrivDataSourceDesc
    forall a. Maybe a
    Nothing (\PrivDataSourceDesc
    d -> PrivDataSourceDesc -> Maybe PrivDataSourceDesc
    forall a. a -> Maybe a
    Just (PrivDataSourceDesc -> Maybe PrivDataSourceDesc)
    -> PrivDataSourceDesc -> Maybe PrivDataSourceDesc
    forall a b. (a -> b) -> a -> b
    $ PrivDataSourceDesc
    "    " PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataSourceDesc
    d) Maybe PrivDataSourceDesc
    md
    		, PrivDataSourceDesc -> Maybe PrivDataSourceDesc
    forall a. a -> Maybe a
    Just PrivDataSourceDesc
    ""
    		]

    addPrivData :: (PrivDataField, Maybe PrivDataSourceDesc, HostContext) -> Property (HasInfo + UnixLike)
    addPrivData :: (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> Property (HasInfo + UnixLike)
    addPrivData (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    v = PrivDataSourceDesc -> PrivInfo -> Property (HasInfo + UnixLike)
    forall v.
    IsInfo v =>
    PrivDataSourceDesc -> v -> Property (HasInfo + UnixLike)
    pureInfoProperty ((PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> PrivDataSourceDesc
    forall a. Show a => a -> PrivDataSourceDesc
    show (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    v) (Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> PrivInfo
    PrivInfo ((PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    forall a. a -> Set a
    S.singleton (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    v))

    {- Gets the requested field's value, in the specified context if it's
     - available, from the host's local privdata cache. -}
    getLocalPrivData :: PrivDataField -> Context -> IO (Maybe PrivData)
    getLocalPrivData :: PrivDataField -> Context -> IO (Maybe PrivData)
    getLocalPrivData PrivDataField
    field Context
    context =
    	PrivDataField -> Context -> PrivMap -> Maybe PrivData
    getPrivData PrivDataField
    field Context
    context (PrivMap -> Maybe PrivData)
    -> (Maybe PrivMap -> PrivMap) -> Maybe PrivMap -> Maybe PrivData
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrivMap -> Maybe PrivMap -> PrivMap
    forall a. a -> Maybe a -> a
    fromMaybe PrivMap
    forall k a. Map k a
    M.empty (Maybe PrivMap -> Maybe PrivData)
    -> IO (Maybe PrivMap) -> IO (Maybe PrivData)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO (Maybe PrivMap)
    localcache
      where
    	localcache :: IO (Maybe PrivMap)
    localcache = Maybe PrivMap -> IO (Maybe PrivMap) -> IO (Maybe PrivMap)
    forall (m :: * -> *) a. MonadCatch m => a -> m a -> m a
    catchDefaultIO Maybe PrivMap
    forall a. Maybe a
    Nothing (IO (Maybe PrivMap) -> IO (Maybe PrivMap))
    -> IO (Maybe PrivMap) -> IO (Maybe PrivMap)
    forall a b. (a -> b) -> a -> b
    $ PrivDataSourceDesc -> Maybe PrivMap
    forall a. Read a => PrivDataSourceDesc -> Maybe a
    readish (PrivDataSourceDesc -> Maybe PrivMap)
    -> IO PrivDataSourceDesc -> IO (Maybe PrivMap)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> PrivDataSourceDesc -> IO PrivDataSourceDesc
    readFile PrivDataSourceDesc
    privDataLocal

    type PrivMap = M.Map (PrivDataField, Context) String

    -- | Get only the set of PrivData that the Host's Info says it uses.
    filterPrivData :: Host -> PrivMap -> PrivMap
    filterPrivData :: Host -> PrivMap -> PrivMap
    filterPrivData Host
    host = ((PrivDataField, Context) -> PrivDataSourceDesc -> Bool)
    -> PrivMap -> PrivMap
    forall k a. (k -> a -> Bool) -> Map k a -> Map k a
    M.filterWithKey (\(PrivDataField, Context)
    k PrivDataSourceDesc
    _v -> (PrivDataField, Context) -> Set (PrivDataField, Context) -> Bool
    forall a. Ord a => a -> Set a -> Bool
    S.member (PrivDataField, Context)
    k Set (PrivDataField, Context)
    used)
      where
    	used :: Set (PrivDataField, Context)
    used = ((PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> (PrivDataField, Context))
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> Set (PrivDataField, Context)
    forall b a. Ord b => (a -> b) -> Set a -> Set b
    S.map (\(PrivDataField
    f, Maybe PrivDataSourceDesc
    _, HostContext
    c) -> (PrivDataField
    f, HostContext -> PrivDataSourceDesc -> Context
    mkHostContext HostContext
    c (Host -> PrivDataSourceDesc
    hostName Host
    host))) (Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> Set (PrivDataField, Context))
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> Set (PrivDataField, Context)
    forall a b. (a -> b) -> a -> b
    $
    		PrivInfo
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    fromPrivInfo (PrivInfo
     -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext))
    -> PrivInfo
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    forall a b. (a -> b) -> a -> b
    $ Info -> PrivInfo
    forall v. IsInfo v => Info -> v
    fromInfo (Info -> PrivInfo) -> Info -> PrivInfo
    forall a b. (a -> b) -> a -> b
    $ Host -> Info
    hostInfo Host
    host

    getPrivData :: PrivDataField -> Context -> PrivMap -> Maybe PrivData
    getPrivData :: PrivDataField -> Context -> PrivMap -> Maybe PrivData
    getPrivData PrivDataField
    field Context
    context PrivMap
    m = do
    	s <- (PrivDataField, Context) -> PrivMap -> Maybe PrivDataSourceDesc
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup (PrivDataField
    field, Context
    context) PrivMap
    m
    	return (PrivData s)

    setPrivData :: PrivDataField -> Context -> IO ()
    setPrivData :: PrivDataField -> Context -> IO ()
    setPrivData PrivDataField
    field Context
    context = do
    	PrivDataSourceDesc -> IO ()
    putStrLn PrivDataSourceDesc
    "Enter private data on stdin; ctrl-D when done:"
    	PrivDataField -> Context -> PrivData -> IO ()
    setPrivDataTo PrivDataField
    field Context
    context (PrivData -> IO ())
    -> (PrivDataSourceDesc -> PrivData) -> PrivDataSourceDesc -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrivDataSourceDesc -> PrivData
    PrivData (PrivDataSourceDesc -> IO ()) -> IO PrivDataSourceDesc -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Handle -> IO PrivDataSourceDesc
    hGetContentsStrict Handle
    stdin

    unsetPrivData :: PrivDataField -> Context -> IO ()
    unsetPrivData :: PrivDataField -> Context -> IO ()
    unsetPrivData PrivDataField
    field Context
    context = do
    	(PrivMap -> PrivMap) -> IO ()
    modifyPrivData ((PrivMap -> PrivMap) -> IO ()) -> (PrivMap -> PrivMap) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ (PrivDataField, Context) -> PrivMap -> PrivMap
    forall k a. Ord k => k -> Map k a -> Map k a
    M.delete (PrivDataField
    field, Context
    context)
    	PrivDataField -> Context -> IO ()
    descUnset PrivDataField
    field Context
    context

    descUnset :: PrivDataField -> Context -> IO ()
    descUnset :: PrivDataField -> Context -> IO ()
    descUnset PrivDataField
    field Context
    context =
    	PrivDataSourceDesc -> IO ()
    putStrLn (PrivDataSourceDesc -> IO ()) -> PrivDataSourceDesc -> IO ()
    forall a b. (a -> b) -> a -> b
    $ PrivDataSourceDesc
    "Private data unset: " PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataField -> PrivDataSourceDesc
    forall a. Show a => a -> PrivDataSourceDesc
    show PrivDataField
    field PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataSourceDesc
    " " PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ Context -> PrivDataSourceDesc
    forall a. Show a => a -> PrivDataSourceDesc
    show Context
    context

    unsetPrivDataUnused :: [Host] -> IO ()
    unsetPrivDataUnused :: [Host] -> IO ()
    unsetPrivDataUnused [Host]
    hosts = do
    	deleted <- (PrivMap -> (PrivMap, [(PrivDataField, Context)]))
    -> IO [(PrivDataField, Context)]
    forall a. (PrivMap -> (PrivMap, a)) -> IO a
    modifyPrivData' ((PrivMap -> (PrivMap, [(PrivDataField, Context)]))
     -> IO [(PrivDataField, Context)])
    -> (PrivMap -> (PrivMap, [(PrivDataField, Context)]))
    -> IO [(PrivDataField, Context)]
    forall a b. (a -> b) -> a -> b
    $ \PrivMap
    m ->
    		let (PrivMap
    keep, PrivMap
    del) = ((PrivDataField, Context) -> PrivDataSourceDesc -> Bool)
    -> PrivMap -> (PrivMap, PrivMap)
    forall k a. (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)
    M.partitionWithKey (\(PrivDataField, Context)
    k PrivDataSourceDesc
    _ -> (PrivDataField, Context)
    k (PrivDataField, Context)
    -> Map (PrivDataField, Context) [PrivDataSourceDesc] -> Bool
    forall k a. Ord k => k -> Map k a -> Bool
    `M.member` Map (PrivDataField, Context) [PrivDataSourceDesc]
    usedby) PrivMap
    m
    		in (PrivMap
    keep, PrivMap -> [(PrivDataField, Context)]
    forall k a. Map k a -> [k]
    M.keys PrivMap
    del)
    	mapM_ (uncurry descUnset) deleted
      where
    	usedby :: Map (PrivDataField, Context) [PrivDataSourceDesc]
    usedby = [Host] -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    mkUsedByMap [Host]
    hosts

    dumpPrivData :: PrivDataField -> Context -> IO ()
    dumpPrivData :: PrivDataField -> Context -> IO ()
    dumpPrivData PrivDataField
    field Context
    context = do
    	IO () -> (PrivData -> IO ()) -> Maybe PrivData -> IO ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (PrivDataSourceDesc -> IO ()
    forall a. HasCallStack => PrivDataSourceDesc -> a
    error PrivDataSourceDesc
    "Requested privdata is not set.")
    		(Handle -> ByteString -> IO ()
    L.hPut Handle
    stdout (ByteString -> IO ())
    -> (PrivData -> ByteString) -> PrivData -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrivData -> ByteString
    privDataByteString)
    		(Maybe PrivData -> IO ()) -> IO (Maybe PrivData) -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< (PrivDataField -> Context -> PrivMap -> Maybe PrivData
    getPrivData PrivDataField
    field Context
    context (PrivMap -> Maybe PrivData) -> IO PrivMap -> IO (Maybe PrivData)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO PrivMap
    decryptPrivData)

    editPrivData :: PrivDataField -> Context -> IO ()
    editPrivData :: PrivDataField -> Context -> IO ()
    editPrivData PrivDataField
    field Context
    context = do
    	v <- PrivDataField -> Context -> PrivMap -> Maybe PrivData
    getPrivData PrivDataField
    field Context
    context (PrivMap -> Maybe PrivData) -> IO PrivMap -> IO (Maybe PrivData)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO PrivMap
    decryptPrivData
    	v' <- withTmpFile "propellorXXXX" $ \PrivDataSourceDesc
    f Handle
    th -> do
    		Handle -> IO ()
    hClose Handle
    th
    		IO () -> (PrivData -> IO ()) -> Maybe PrivData -> IO ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe IO ()
    forall (m :: * -> *). Monad m => m ()
    noop (\PrivData
    p -> PrivDataSourceDesc -> (Handle -> IO ()) -> IO ()
    writeFileProtected' PrivDataSourceDesc
    f (Handle -> ByteString -> IO ()
    `L.hPut` PrivData -> ByteString
    privDataByteString PrivData
    p)) Maybe PrivData
    v
    		editor <- PrivDataSourceDesc -> PrivDataSourceDesc -> IO PrivDataSourceDesc
    getEnvDefault PrivDataSourceDesc
    "EDITOR" PrivDataSourceDesc
    "vi"
    		unlessM (boolSystemNonConcurrent editor [File f]) $
    			error "Editor failed; aborting."
    		PrivData <$> readFile f
    	setPrivDataTo field context v'

    listPrivDataFields :: [Host] -> IO ()
    listPrivDataFields :: [Host] -> IO ()
    listPrivDataFields [Host]
    hosts = do
    	m <- IO PrivMap
    decryptPrivData

    	section "Currently set data:"
    	showtable $ map mkrow (M.keys m)
    	let missing = PrivMap -> [(PrivDataField, Context)]
    forall k a. Map k a -> [k]
    M.keys (PrivMap -> [(PrivDataField, Context)])
    -> PrivMap -> [(PrivDataField, Context)]
    forall a b. (a -> b) -> a -> b
    $ PrivMap -> PrivMap -> PrivMap
    forall k a b. Ord k => Map k a -> Map k b -> Map k a
    M.difference PrivMap
    wantedmap PrivMap
    m

    	unless (null missing) $ do
    		section "Missing data that would be used if set:"
    		showtable $ map mkrow missing

    		section "How to set missing data:"
    		mapM_ putStrLn $ showSet $
    			map (\(PrivDataField
    f, Context
    c) -> (PrivDataField
    f, Context
    c, Maybe (Maybe PrivDataSourceDesc) -> Maybe PrivDataSourceDesc
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (Maybe (Maybe PrivDataSourceDesc) -> Maybe PrivDataSourceDesc)
    -> Maybe (Maybe PrivDataSourceDesc) -> Maybe PrivDataSourceDesc
    forall a b. (a -> b) -> a -> b
    $ (PrivDataField, Context)
    -> Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)
    -> Maybe (Maybe PrivDataSourceDesc)
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup (PrivDataField
    f, Context
    c) Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)
    descmap)) missing
      where
    	header :: [PrivDataSourceDesc]
    header = [PrivDataSourceDesc
    "Field", PrivDataSourceDesc
    "Context", PrivDataSourceDesc
    "Used by"]
    	mkrow :: (PrivDataField, Context) -> [PrivDataSourceDesc]
    mkrow k :: (PrivDataField, Context)
    k@(PrivDataField
    field, Context PrivDataSourceDesc
    context) =
    		[ PrivDataSourceDesc -> PrivDataSourceDesc
    shellEscape (PrivDataSourceDesc -> PrivDataSourceDesc)
    -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a b. (a -> b) -> a -> b
    $ PrivDataField -> PrivDataSourceDesc
    forall a. Show a => a -> PrivDataSourceDesc
    show PrivDataField
    field
    		, PrivDataSourceDesc -> PrivDataSourceDesc
    shellEscape PrivDataSourceDesc
    context
    		, PrivDataSourceDesc -> [PrivDataSourceDesc] -> PrivDataSourceDesc
    forall a. [a] -> [[a]] -> [a]
    intercalate PrivDataSourceDesc
    ", " ([PrivDataSourceDesc] -> PrivDataSourceDesc)
    -> [PrivDataSourceDesc] -> PrivDataSourceDesc
    forall a b. (a -> b) -> a -> b
    $ [PrivDataSourceDesc] -> [PrivDataSourceDesc]
    forall a. Ord a => [a] -> [a]
    sort ([PrivDataSourceDesc] -> [PrivDataSourceDesc])
    -> [PrivDataSourceDesc] -> [PrivDataSourceDesc]
    forall a b. (a -> b) -> a -> b
    $ [PrivDataSourceDesc]
    -> Maybe [PrivDataSourceDesc] -> [PrivDataSourceDesc]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [PrivDataSourceDesc] -> [PrivDataSourceDesc])
    -> Maybe [PrivDataSourceDesc] -> [PrivDataSourceDesc]
    forall a b. (a -> b) -> a -> b
    $ (PrivDataField, Context)
    -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    -> Maybe [PrivDataSourceDesc]
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup (PrivDataField, Context)
    k Map (PrivDataField, Context) [PrivDataSourceDesc]
    usedby
    		]
    	usedby :: Map (PrivDataField, Context) [PrivDataSourceDesc]
    usedby = [Host] -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    mkUsedByMap [Host]
    hosts
    	wantedmap :: PrivMap
    wantedmap = [((PrivDataField, Context), PrivDataSourceDesc)] -> PrivMap
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([((PrivDataField, Context), PrivDataSourceDesc)] -> PrivMap)
    -> [((PrivDataField, Context), PrivDataSourceDesc)] -> PrivMap
    forall a b. (a -> b) -> a -> b
    $ [(PrivDataField, Context)]
    -> [PrivDataSourceDesc]
    -> [((PrivDataField, Context), PrivDataSourceDesc)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip (Map (PrivDataField, Context) [PrivDataSourceDesc]
    -> [(PrivDataField, Context)]
    forall k a. Map k a -> [k]
    M.keys Map (PrivDataField, Context) [PrivDataSourceDesc]
    usedby) (PrivDataSourceDesc -> [PrivDataSourceDesc]
    forall a. a -> [a]
    repeat PrivDataSourceDesc
    "")
    	descmap :: Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)
    descmap = [Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)]
    -> Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)
    forall (f :: * -> *) k a.
    (Foldable f, Ord k) =>
    f (Map k a) -> Map k a
    M.unions ([Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)]
     -> Map (PrivDataField, Context) (Maybe PrivDataSourceDesc))
    -> [Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)]
    -> Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)
    forall a b. (a -> b) -> a -> b
    $ (Host -> Map (PrivDataField, Context) (Maybe PrivDataSourceDesc))
    -> [Host]
    -> [Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Host
    -> (Maybe PrivDataSourceDesc -> Maybe PrivDataSourceDesc)
    -> Map (PrivDataField, Context) (Maybe PrivDataSourceDesc)
    forall a.
    Host
    -> (Maybe PrivDataSourceDesc -> a)
    -> Map (PrivDataField, Context) a
    `mkPrivDataMap` Maybe PrivDataSourceDesc -> Maybe PrivDataSourceDesc
    forall a. a -> a
    id) [Host]
    hosts
    	section :: PrivDataSourceDesc -> IO ()
    section PrivDataSourceDesc
    desc = PrivDataSourceDesc -> IO ()
    putStrLn (PrivDataSourceDesc -> IO ()) -> PrivDataSourceDesc -> IO ()
    forall a b. (a -> b) -> a -> b
    $ PrivDataSourceDesc
    "\n" PrivDataSourceDesc -> PrivDataSourceDesc -> PrivDataSourceDesc
    forall a. [a] -> [a] -> [a]
    ++ PrivDataSourceDesc
    desc
    	showtable :: [[PrivDataSourceDesc]] -> IO ()
    showtable [[PrivDataSourceDesc]]
    rows = do
    		PrivDataSourceDesc -> IO ()
    putStr (PrivDataSourceDesc -> IO ()) -> PrivDataSourceDesc -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [PrivDataSourceDesc] -> PrivDataSourceDesc
    unlines ([PrivDataSourceDesc] -> PrivDataSourceDesc)
    -> [PrivDataSourceDesc] -> PrivDataSourceDesc
    forall a b. (a -> b) -> a -> b
    $ [[PrivDataSourceDesc]] -> [PrivDataSourceDesc]
    formatTable ([[PrivDataSourceDesc]] -> [PrivDataSourceDesc])
    -> [[PrivDataSourceDesc]] -> [PrivDataSourceDesc]
    forall a b. (a -> b) -> a -> b
    $ [PrivDataSourceDesc]
    -> [[PrivDataSourceDesc]] -> [[PrivDataSourceDesc]]
    tableWithHeader [PrivDataSourceDesc]
    header [[PrivDataSourceDesc]]
    rows

    mkUsedByMap :: [Host] -> M.Map (PrivDataField, Context) [HostName]
    mkUsedByMap :: [Host] -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    mkUsedByMap = ([PrivDataSourceDesc]
     -> [PrivDataSourceDesc] -> [PrivDataSourceDesc])
    -> [Map (PrivDataField, Context) [PrivDataSourceDesc]]
    -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    forall (f :: * -> *) k a.
    (Foldable f, Ord k) =>
    (a -> a -> a) -> f (Map k a) -> Map k a
    M.unionsWith [PrivDataSourceDesc]
    -> [PrivDataSourceDesc] -> [PrivDataSourceDesc]
    forall a. [a] -> [a] -> [a]
    (++) ([Map (PrivDataField, Context) [PrivDataSourceDesc]]
     -> Map (PrivDataField, Context) [PrivDataSourceDesc])
    -> ([Host] -> [Map (PrivDataField, Context) [PrivDataSourceDesc]])
    -> [Host]
    -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Host -> Map (PrivDataField, Context) [PrivDataSourceDesc])
    -> [Host] -> [Map (PrivDataField, Context) [PrivDataSourceDesc]]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Host
    h -> Host
    -> (Maybe PrivDataSourceDesc -> [PrivDataSourceDesc])
    -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    forall a.
    Host
    -> (Maybe PrivDataSourceDesc -> a)
    -> Map (PrivDataField, Context) a
    mkPrivDataMap Host
    h ((Maybe PrivDataSourceDesc -> [PrivDataSourceDesc])
     -> Map (PrivDataField, Context) [PrivDataSourceDesc])
    -> (Maybe PrivDataSourceDesc -> [PrivDataSourceDesc])
    -> Map (PrivDataField, Context) [PrivDataSourceDesc]
    forall a b. (a -> b) -> a -> b
    $ [PrivDataSourceDesc]
    -> Maybe PrivDataSourceDesc -> [PrivDataSourceDesc]
    forall a b. a -> b -> a
    const [Host -> PrivDataSourceDesc
    hostName Host
    h])

    mkPrivDataMap :: Host -> (Maybe PrivDataSourceDesc -> a) -> M.Map (PrivDataField, Context) a
    mkPrivDataMap :: forall a.
    Host
    -> (Maybe PrivDataSourceDesc -> a)
    -> Map (PrivDataField, Context) a
    mkPrivDataMap Host
    host Maybe PrivDataSourceDesc -> a
    mkv = [((PrivDataField, Context), a)] -> Map (PrivDataField, Context) a
    forall k a. Ord k => [(k, a)] -> Map k a
    M.fromList ([((PrivDataField, Context), a)] -> Map (PrivDataField, Context) a)
    -> [((PrivDataField, Context), a)]
    -> Map (PrivDataField, Context) a
    forall a b. (a -> b) -> a -> b
    $
    	((PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> ((PrivDataField, Context), a))
    -> [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
    -> [((PrivDataField, Context), a)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(PrivDataField
    f, Maybe PrivDataSourceDesc
    d, HostContext
    c) -> ((PrivDataField
    f, HostContext -> PrivDataSourceDesc -> Context
    mkHostContext HostContext
    c (Host -> PrivDataSourceDesc
    hostName Host
    host)), Maybe PrivDataSourceDesc -> a
    mkv Maybe PrivDataSourceDesc
    d))
    		(Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
    forall a. Set a -> [a]
    S.toList (Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)])
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> [(PrivDataField, Maybe PrivDataSourceDesc, HostContext)]
    forall a b. (a -> b) -> a -> b
    $ PrivInfo
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    fromPrivInfo (PrivInfo
     -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext))
    -> PrivInfo
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    forall a b. (a -> b) -> a -> b
    $ Info -> PrivInfo
    forall v. IsInfo v => Info -> v
    fromInfo (Info -> PrivInfo) -> Info -> PrivInfo
    forall a b. (a -> b) -> a -> b
    $ Host -> Info
    hostInfo Host
    host)

    setPrivDataTo :: PrivDataField -> Context -> PrivData -> IO ()
    setPrivDataTo :: PrivDataField -> Context -> PrivData -> IO ()
    setPrivDataTo PrivDataField
    field Context
    context (PrivData PrivDataSourceDesc
    value) = do
    	(PrivMap -> PrivMap) -> IO ()
    modifyPrivData PrivMap -> PrivMap
    set
    	PrivDataSourceDesc -> IO ()
    putStrLn PrivDataSourceDesc
    "Private data set."
      where
    	set :: PrivMap -> PrivMap
    set = (PrivDataField, Context)
    -> PrivDataSourceDesc -> PrivMap -> PrivMap
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert (PrivDataField
    field, Context
    context) PrivDataSourceDesc
    value

    modifyPrivData :: (PrivMap -> PrivMap) -> IO ()
    modifyPrivData :: (PrivMap -> PrivMap) -> IO ()
    modifyPrivData PrivMap -> PrivMap
    f = (PrivMap -> (PrivMap, ())) -> IO ()
    forall a. (PrivMap -> (PrivMap, a)) -> IO a
    modifyPrivData' (\PrivMap
    m -> (PrivMap -> PrivMap
    f PrivMap
    m, ()))

    modifyPrivData' :: (PrivMap -> (PrivMap, a)) -> IO a
    modifyPrivData' :: forall a. (PrivMap -> (PrivMap, a)) -> IO a
    modifyPrivData' PrivMap -> (PrivMap, a)
    f = do
    	IO ()
    makePrivDataDir
    	m <- IO PrivMap
    decryptPrivData
    	let (m', r) = f m
    	privdata <- privDataFile
    	gpgEncrypt privdata (show m')
    	void $ boolSystem "git" [Param "add", File privdata]
    	return r

    decryptPrivData :: IO PrivMap
    decryptPrivData :: IO PrivMap
    decryptPrivData = PrivDataSourceDesc -> PrivMap
    readPrivData (PrivDataSourceDesc -> PrivMap)
    -> IO PrivDataSourceDesc -> IO PrivMap
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (PrivDataSourceDesc -> IO PrivDataSourceDesc
    gpgDecrypt (PrivDataSourceDesc -> IO PrivDataSourceDesc)
    -> IO PrivDataSourceDesc -> IO PrivDataSourceDesc
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< IO PrivDataSourceDesc
    privDataFile)

    readPrivData :: String -> PrivMap
    readPrivData :: PrivDataSourceDesc -> PrivMap
    readPrivData = PrivMap -> Maybe PrivMap -> PrivMap
    forall a. a -> Maybe a -> a
    fromMaybe PrivMap
    forall k a. Map k a
    M.empty (Maybe PrivMap -> PrivMap)
    -> (PrivDataSourceDesc -> Maybe PrivMap)
    -> PrivDataSourceDesc
    -> PrivMap
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrivDataSourceDesc -> Maybe PrivMap
    forall a. Read a => PrivDataSourceDesc -> Maybe a
    readish

    readPrivDataFile :: FilePath -> IO PrivMap
    readPrivDataFile :: PrivDataSourceDesc -> IO PrivMap
    readPrivDataFile PrivDataSourceDesc
    f = PrivDataSourceDesc -> PrivMap
    readPrivData (PrivDataSourceDesc -> PrivMap)
    -> IO PrivDataSourceDesc -> IO PrivMap
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> PrivDataSourceDesc -> IO PrivDataSourceDesc
    readFileStrict PrivDataSourceDesc
    f

    makePrivDataDir :: IO ()
    makePrivDataDir :: IO ()
    makePrivDataDir = Bool -> PrivDataSourceDesc -> IO ()
    createDirectoryIfMissing Bool
    False PrivDataSourceDesc
    privDataDir

    newtype PrivInfo = PrivInfo
    	{ PrivInfo
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    fromPrivInfo :: S.Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext) }
    	deriving (PrivInfo -> PrivInfo -> Bool
    (PrivInfo -> PrivInfo -> Bool)
    -> (PrivInfo -> PrivInfo -> Bool) -> Eq PrivInfo
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PrivInfo -> PrivInfo -> Bool
    == :: PrivInfo -> PrivInfo -> Bool
    $c/= :: PrivInfo -> PrivInfo -> Bool
    /= :: PrivInfo -> PrivInfo -> Bool
    Eq, Eq PrivInfo
    Eq PrivInfo =>
    (PrivInfo -> PrivInfo -> Ordering)
    -> (PrivInfo -> PrivInfo -> Bool)
    -> (PrivInfo -> PrivInfo -> Bool)
    -> (PrivInfo -> PrivInfo -> Bool)
    -> (PrivInfo -> PrivInfo -> Bool)
    -> (PrivInfo -> PrivInfo -> PrivInfo)
    -> (PrivInfo -> PrivInfo -> PrivInfo)
    -> Ord PrivInfo
    PrivInfo -> PrivInfo -> Bool
    PrivInfo -> PrivInfo -> Ordering
    PrivInfo -> PrivInfo -> PrivInfo
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: PrivInfo -> PrivInfo -> Ordering
    compare :: PrivInfo -> PrivInfo -> Ordering
    $c< :: PrivInfo -> PrivInfo -> Bool
    < :: PrivInfo -> PrivInfo -> Bool
    $c<= :: PrivInfo -> PrivInfo -> Bool
    <= :: PrivInfo -> PrivInfo -> Bool
    $c> :: PrivInfo -> PrivInfo -> Bool
    > :: PrivInfo -> PrivInfo -> Bool
    $c>= :: PrivInfo -> PrivInfo -> Bool
    >= :: PrivInfo -> PrivInfo -> Bool
    $cmax :: PrivInfo -> PrivInfo -> PrivInfo
    max :: PrivInfo -> PrivInfo -> PrivInfo
    $cmin :: PrivInfo -> PrivInfo -> PrivInfo
    min :: PrivInfo -> PrivInfo -> PrivInfo
    Ord, Int -> PrivInfo -> PrivDataSourceDesc -> PrivDataSourceDesc
    [PrivInfo] -> PrivDataSourceDesc -> PrivDataSourceDesc
    PrivInfo -> PrivDataSourceDesc
    (Int -> PrivInfo -> PrivDataSourceDesc -> PrivDataSourceDesc)
    -> (PrivInfo -> PrivDataSourceDesc)
    -> ([PrivInfo] -> PrivDataSourceDesc -> PrivDataSourceDesc)
    -> Show PrivInfo
    forall a.
    (Int -> a -> PrivDataSourceDesc -> PrivDataSourceDesc)
    -> (a -> PrivDataSourceDesc)
    -> ([a] -> PrivDataSourceDesc -> PrivDataSourceDesc)
    -> Show a
    $cshowsPrec :: Int -> PrivInfo -> PrivDataSourceDesc -> PrivDataSourceDesc
    showsPrec :: Int -> PrivInfo -> PrivDataSourceDesc -> PrivDataSourceDesc
    $cshow :: PrivInfo -> PrivDataSourceDesc
    show :: PrivInfo -> PrivDataSourceDesc
    $cshowList :: [PrivInfo] -> PrivDataSourceDesc -> PrivDataSourceDesc
    showList :: [PrivInfo] -> PrivDataSourceDesc -> PrivDataSourceDesc
    Show, Typeable, NonEmpty PrivInfo -> PrivInfo
    PrivInfo -> PrivInfo -> PrivInfo
    (PrivInfo -> PrivInfo -> PrivInfo)
    -> (NonEmpty PrivInfo -> PrivInfo)
    -> (forall b. Integral b => b -> PrivInfo -> PrivInfo)
    -> Semigroup PrivInfo
    forall b. Integral b => b -> PrivInfo -> PrivInfo
    forall a.
    (a -> a -> a)
    -> (NonEmpty a -> a)
    -> (forall b. Integral b => b -> a -> a)
    -> Semigroup a
    $c<> :: PrivInfo -> PrivInfo -> PrivInfo
    <> :: PrivInfo -> PrivInfo -> PrivInfo
    $csconcat :: NonEmpty PrivInfo -> PrivInfo
    sconcat :: NonEmpty PrivInfo -> PrivInfo
    $cstimes :: forall b. Integral b => b -> PrivInfo -> PrivInfo
    stimes :: forall b. Integral b => b -> PrivInfo -> PrivInfo
    Sem.Semigroup, Semigroup PrivInfo
    PrivInfo
    Semigroup PrivInfo =>
    PrivInfo
    -> (PrivInfo -> PrivInfo -> PrivInfo)
    -> ([PrivInfo] -> PrivInfo)
    -> Monoid PrivInfo
    [PrivInfo] -> PrivInfo
    PrivInfo -> PrivInfo -> PrivInfo
    forall a.
    Semigroup a =>
    a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
    $cmempty :: PrivInfo
    mempty :: PrivInfo
    $cmappend :: PrivInfo -> PrivInfo -> PrivInfo
    mappend :: PrivInfo -> PrivInfo -> PrivInfo
    $cmconcat :: [PrivInfo] -> PrivInfo
    mconcat :: [PrivInfo] -> PrivInfo
    Monoid)

    -- PrivInfo always propagates out of containers, so that propellor
    -- can see which hosts need it.
    instance IsInfo PrivInfo where
    	propagateInfo :: PrivInfo -> PropagateInfo
    propagateInfo PrivInfo
    _ = PropagateInfo
    PropagatePrivData

    -- | Sets the context of any privdata that uses HostContext to the
    -- provided name.
    forceHostContext :: String -> PrivInfo -> PrivInfo
    forceHostContext :: PrivDataSourceDesc -> PrivInfo -> PrivInfo
    forceHostContext PrivDataSourceDesc
    name PrivInfo
    i = Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> PrivInfo
    PrivInfo (Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> PrivInfo)
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> PrivInfo
    forall a b. (a -> b) -> a -> b
    $ ((PrivDataField, Maybe PrivDataSourceDesc, HostContext)
     -> (PrivDataField, Maybe PrivDataSourceDesc, HostContext))
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    forall b a. Ord b => (a -> b) -> Set a -> Set b
    S.map (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    go (PrivInfo
    -> Set (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    fromPrivInfo PrivInfo
    i)
      where
    	go :: (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    -> (PrivDataField, Maybe PrivDataSourceDesc, HostContext)
    go (PrivDataField
    f, Maybe PrivDataSourceDesc
    d, HostContext PrivDataSourceDesc -> Context
    ctx) = (PrivDataField
    f, Maybe PrivDataSourceDesc
    d, (PrivDataSourceDesc -> Context) -> HostContext
    HostContext (Context -> PrivDataSourceDesc -> Context
    forall a b. a -> b -> a
    const (Context -> PrivDataSourceDesc -> Context)
    -> Context -> PrivDataSourceDesc -> Context
    forall a b. (a -> b) -> a -> b
    $ PrivDataSourceDesc -> Context
    ctx PrivDataSourceDesc
    name))