module B9.B9Config.Docker
  ( dockerConfigToCPDocument,
    defaultDockerConfig,
    parseDockerConfig,
    DockerConfig (..),
    dockerNetworkId,
    dockerCapabilities,
  )
where

import B9.B9Config.Container
import Control.Lens (makeLenses)
import Data.ConfigFile.B9Extras

data DockerConfig
  = DockerConfig
      { DockerConfig -> Maybe String
_dockerNetworkId :: Maybe String,
        DockerConfig -> [ContainerCapability]
_dockerCapabilities :: [ContainerCapability]
      }
  deriving (ReadPrec [DockerConfig]
ReadPrec DockerConfig
Int -> ReadS DockerConfig
ReadS [DockerConfig]
(Int -> ReadS DockerConfig)
-> ReadS [DockerConfig]
-> ReadPrec DockerConfig
-> ReadPrec [DockerConfig]
-> Read DockerConfig
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DockerConfig]
$creadListPrec :: ReadPrec [DockerConfig]
readPrec :: ReadPrec DockerConfig
$creadPrec :: ReadPrec DockerConfig
readList :: ReadS [DockerConfig]
$creadList :: ReadS [DockerConfig]
readsPrec :: Int -> ReadS DockerConfig
$creadsPrec :: Int -> ReadS DockerConfig
Read, Int -> DockerConfig -> ShowS
[DockerConfig] -> ShowS
DockerConfig -> String
(Int -> DockerConfig -> ShowS)
-> (DockerConfig -> String)
-> ([DockerConfig] -> ShowS)
-> Show DockerConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DockerConfig] -> ShowS
$cshowList :: [DockerConfig] -> ShowS
show :: DockerConfig -> String
$cshow :: DockerConfig -> String
showsPrec :: Int -> DockerConfig -> ShowS
$cshowsPrec :: Int -> DockerConfig -> ShowS
Show, DockerConfig -> DockerConfig -> Bool
(DockerConfig -> DockerConfig -> Bool)
-> (DockerConfig -> DockerConfig -> Bool) -> Eq DockerConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DockerConfig -> DockerConfig -> Bool
$c/= :: DockerConfig -> DockerConfig -> Bool
== :: DockerConfig -> DockerConfig -> Bool
$c== :: DockerConfig -> DockerConfig -> Bool
Eq)

makeLenses ''DockerConfig

defaultDockerConfig :: DockerConfig
defaultDockerConfig :: DockerConfig
defaultDockerConfig =
  Maybe String -> [ContainerCapability] -> DockerConfig
DockerConfig
    Maybe String
forall a. Maybe a
Nothing
    [ ContainerCapability
CAP_MKNOD,
      ContainerCapability
CAP_SYS_ADMIN,
      ContainerCapability
CAP_SYS_CHROOT,
      ContainerCapability
CAP_SETGID,
      ContainerCapability
CAP_SETUID,
      ContainerCapability
CAP_NET_BIND_SERVICE,
      ContainerCapability
CAP_SETPCAP,
      ContainerCapability
CAP_SYS_PTRACE,
      ContainerCapability
CAP_SYS_MODULE
    ]

cfgFileSection :: String
cfgFileSection :: String
cfgFileSection = String
"docker"

networkIdK :: String
networkIdK :: String
networkIdK = String
"network"

dockerConfigToCPDocument ::
  DockerConfig -> CPDocument -> Either CPError CPDocument
dockerConfigToCPDocument :: DockerConfig -> CPDocument -> Either CPError CPDocument
dockerConfigToCPDocument DockerConfig
c CPDocument
cp = do
  CPDocument
cp1 <- CPDocument -> String -> Either CPError CPDocument
forall (m :: * -> *).
MonadError CPError m =>
CPDocument -> String -> m CPDocument
addSectionCP CPDocument
cp String
cfgFileSection
  CPDocument
cp2 <-
    CPDocument
-> String -> String -> Maybe String -> Either CPError CPDocument
forall a (m :: * -> *).
(Show a, MonadError CPError m) =>
CPDocument -> String -> String -> a -> m CPDocument
setShowCP CPDocument
cp1 String
cfgFileSection String
networkIdK (Maybe String -> Either CPError CPDocument)
-> Maybe String -> Either CPError CPDocument
forall a b. (a -> b) -> a -> b
$
      DockerConfig -> Maybe String
_dockerNetworkId DockerConfig
c
  CPDocument
-> String -> [ContainerCapability] -> Either CPError CPDocument
containerCapsToCPDocument CPDocument
cp2 String
cfgFileSection ([ContainerCapability] -> Either CPError CPDocument)
-> [ContainerCapability] -> Either CPError CPDocument
forall a b. (a -> b) -> a -> b
$
    DockerConfig -> [ContainerCapability]
_dockerCapabilities DockerConfig
c

parseDockerConfig :: CPDocument -> Either CPError DockerConfig
parseDockerConfig :: CPDocument -> Either CPError DockerConfig
parseDockerConfig CPDocument
cp =
  let getr :: (CPGet a) => CPOptionSpec -> Either CPError a
      getr :: String -> Either CPError a
getr = CPDocument -> String -> String -> Either CPError a
forall a (m :: * -> *).
(CPGet a, MonadError CPError m) =>
CPDocument -> String -> String -> m a
readCP CPDocument
cp String
cfgFileSection
   in Maybe String -> [ContainerCapability] -> DockerConfig
DockerConfig
        (Maybe String -> [ContainerCapability] -> DockerConfig)
-> Either CPError (Maybe String)
-> Either CPError ([ContainerCapability] -> DockerConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Either CPError (Maybe String)
forall a. CPGet a => String -> Either CPError a
getr String
networkIdK
        Either CPError ([ContainerCapability] -> DockerConfig)
-> Either CPError [ContainerCapability]
-> Either CPError DockerConfig
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CPDocument -> String -> Either CPError [ContainerCapability]
parseContainerCapabilities CPDocument
cp String
cfgFileSection