@@ -76,6 +76,28 @@ module Docker.Client.Types (
76 , HostConfig(..)
76 , HostConfig(..)
77 , defaultHostConfig
77 , defaultHostConfig
78 , NetworkingConfig(..)
78 , NetworkingConfig(..)
84+ , NetworkContainer(..)
89+ , defaultNetworkFilter
91+ , defaultConnectConfig
92+ , DisconnectConfig(..)
93+ , defaultDisconnectConfig
96+ , NetworksDeleted(..)
97+ , EndpointSettings(..)
98+ , defaultEndpointSettings
100+ , defaultIPAMSettings
79 , EndpointConfig(..)
101 , EndpointConfig(..)
80 , Ulimit(..)
102 , Ulimit(..)
81 , ContainerResources(..)
103 , ContainerResources(..)
@@ -100,6 +122,7 @@ module Docker.Client.Types (
100 , MemoryConstraintSize(..)
122 , MemoryConstraintSize(..)
125+import Control.Monad (join)
103import Data.Aeson (FromJSON, ToJSON, genericParseJSON,
126import Data.Aeson (FromJSON, ToJSON, genericParseJSON,
104 genericToJSON, object, parseJSON, toJSON,
127 genericToJSON, object, parseJSON, toJSON,
105 (.!=), (.:), (.:?), (.=))
128 (.!=), (.:), (.:?), (.=))
@@ -107,6 +130,7 @@ import qualified Data.Aeson as JSON
107import Data.Aeson.Types (defaultOptions, fieldLabelModifier)
130import Data.Aeson.Types (defaultOptions, fieldLabelModifier)
108import Data.Char (isAlphaNum, toUpper)
131import Data.Char (isAlphaNum, toUpper)
109import qualified Data.HashMap.Strict as HM
132import qualified Data.HashMap.Strict as HM
133+import Data.Maybe (maybeToList, catMaybes)
110import Data.Monoid ((<>))
134import Data.Monoid ((<>))
111import Data.Scientific (floatingOrInteger)
135import Data.Scientific (floatingOrInteger)
112import Data.Text (Text)
136import Data.Text (Text)
@@ -114,6 +138,7 @@ import qualified Data.Text as T
114import Data.Time.Clock (UTCTime)
138import Data.Time.Clock (UTCTime)
115import qualified Data.Vector as V
139import qualified Data.Vector as V
116import GHC.Generics (Generic)
140import GHC.Generics (Generic)
141+import Numeric (readDec)
117import Prelude hiding (all, tail)
142import Prelude hiding (all, tail)
118import Text.Read (readMaybe)
143import Text.Read (readMaybe)
@@ -139,6 +164,11 @@ data Endpoint =
139 | DeleteImageEndpoint ImageDeleteOpts ImageID
164 | DeleteImageEndpoint ImageDeleteOpts ImageID
140 | CreateNetworkEndpoint CreateNetworkOpts
165 | CreateNetworkEndpoint CreateNetworkOpts
141 | RemoveNetworkEndpoint NetworkID
166 | RemoveNetworkEndpoint NetworkID
167+ | ListNetworksEndpoint NetworkFilter
168+ | InspectNetworkEndpoint NetworkID
169+ | ConnectNetworkEndpoint NetworkID ConnectConfig
170+ | DisconnectNetworkEndpoint NetworkID DisconnectConfig
171+ | PruneNetworksEndpoint PruneFilter
142 deriving (Eq, Show)
172 deriving (Eq, Show)
144-- | We should newtype this
174-- | We should newtype this
@@ -858,6 +888,248 @@ instance ToJSON CreateNetworkOpts where
858 , "EnableIPv6" .= createNetworkEnableIPv6 opts
888 , "EnableIPv6" .= createNetworkEnableIPv6 opts
891+data NetworkScope = LocalScope | GlobalScope | SwarmScope deriving (Eq, Show)
893+fromNetworkScope :: NetworkScope -> Text
894+fromNetworkScope LocalScope = "local"
895+fromNetworkScope GlobalScope = "global"
896+fromNetworkScope SwarmScope = "swarm"
898+instance ToJSON NetworkScope where
899+ toJSON = JSON.String . fromNetworkScope
901+instance FromJSON NetworkScope where
902+ parseJSON "local" = return LocalScope
903+ parseJSON "global" = return GlobalScope
904+ parseJSON "swarm" = return SwarmScope
905+ parseJSON _ = fail "Failed to parse NetworkScope"
907+data CIDR = CIDR Text Int deriving (Eq, Show)
909+instance FromJSON CIDR where
910+ parseJSON (JSON.String t) = case T.splitOn "/" t of
911+ [a,p] -> CIDR a <$> parsePrefixLen p
912+ _ -> fail "Failed to parse CIDR"
914+ parsePrefixLen p = case readDec (T.unpack p) of
915+ (n,""):_ -> return n
916+ _ -> fail "Failed to parse CIDR prefix length"
917+ parseJSON _ = fail "Failed to parse CIDR"
919+data IPAMDriver = DefaultIPAMDriver | NamedIPAMDriver Text deriving (Eq, Show)
921+instance FromJSON IPAMDriver where
922+ parseJSON (JSON.String "default") = return DefaultIPAMDriver
923+ parseJSON (JSON.String t) = return $ NamedIPAMDriver t
924+ parseJSON _ = fail "IPAMDriver is not a string"
926+data IPAMConfig = IPAMConfig
927+ { ipamConfigSubnet :: CIDR
928+ , ipamConfigIPRange :: Maybe CIDR
929+ , ipamSubnetGateway :: Maybe Text
930+ , ipamConfigAuxAddress :: Maybe Text
931+ } deriving (Eq, Show)
933+instance FromJSON IPAMConfig where
934+ parseJSON (JSON.Object o) = IPAMConfig
938+ <*> o .:? "AuxAddress"
939+ parseJSON _ = fail "IPAMConfig is not an object"
942+ { ipamDriver :: IPAMDriver
943+ , ipamConfig :: [IPAMConfig]
944+ , ipamOptions :: HM.HashMap Text Text
945+ } deriving (Eq, Show)
947+instance FromJSON IPAM where
948+ parseJSON (JSON.Object o) = IPAM
949+ <$> o .:? "Driver" .!= DefaultIPAMDriver
950+ <*> o .:? "Config" .!= []
951+ <*> o .:? "Options" .!= HM.empty
952+ parseJSON _ = fail "IPAM is not an object"
954+data NetworkContainer = NetworkContainer
955+ { networkContainerName :: ContainerName
956+ , networkContainerEndpointID :: Text
957+ , networkContainerMacAddress :: Text
958+ , networkContainerIPv4Address :: Text
959+ , networkContainerIPv6Address :: Text
960+ } deriving (Eq, Show)
962+instance FromJSON NetworkContainer where
963+ parseJSON (JSON.Object o) = NetworkContainer
965+ <*> o .: "EndpointID"
966+ <*> o .: "MacAddress"
967+ <*> o .: "IPv4Address"
968+ <*> o .: "IPv6Address"
969+ parseJSON _ = fail "NetworkContainer is not an object"
971+data NetworkDetails = NetworkDetails
972+ { networkDetailsName :: Text
973+ , networkDetailsID :: NetworkID
974+ , networkDetailsCreated :: UTCTime
975+ , networkDetailsScope :: NetworkScope
976+ , networkDetailsDriver :: NetworkMode
977+ , networkDetailsEnableIPv6 :: Bool
978+ , networkDetailsInternal :: Bool
979+ , networkDetailsAttachable :: Bool
980+ , networkDetailsIngress :: Bool
981+ , networkDetailsIPAM :: IPAM
982+ , networkDetailsOptions :: HM.HashMap Text Text
983+ , networkDetailsLabels :: HM.HashMap Text Text
984+ , networkDetailsContainers :: HM.HashMap Text NetworkContainer
985+ } deriving (Eq, Show)
987+instance FromJSON NetworkDetails where
988+ parseJSON v@(JSON.Object o) = NetworkDetails
994+ <*> o .: "EnableIPv6"
996+ <*> o .: "Attachable"
999+ <*> o .:? "Options" .!= HM.empty
1000+ <*> o .:? "Labels" .!= HM.empty
1001+ <*> o .:? "Containers" .!= HM.empty
1002+ parseJSON _ = fail "NetworkDetails is not an object"
1004+data NetworkType = BuiltinNetwork | CustomNetwork deriving (Eq, Show)
1006+fromNetworkType :: NetworkType -> Text
1007+fromNetworkType BuiltinNetwork = "builtin"
1008+fromNetworkType CustomNetwork = "custom"
1010+type NetworkName = Text
1012+instance ToJSON NetworkType where
1013+ toJSON = JSON.String . fromNetworkType
1015+instance FromJSON NetworkType where
1016+ parseJSON (JSON.String "builtin") = return BuiltinNetwork
1017+ parseJSON (JSON.String "custom") = return CustomNetwork
1018+ parseJSON _ = fail "Failed to parse NetworkType"
1020+data NetworkFilter = NetworkFilter
1021+ { networkFilterNames :: [Text]
1022+ , networkFilterIDs :: [NetworkID]
1023+ , networkFilterDrivers :: [NetworkMode]
1024+ , networkFilterScopes :: [NetworkScope]
1025+ , networkFilterTypes :: [NetworkType]
1026+ , networkFilterLabels :: [(Text, (Maybe Text))]
1027+ } deriving (Eq, Show)
1029+instance ToJSON NetworkFilter where
1030+ toJSON nf = object . catMaybes $
1031+ [ "name" .=? networkFilterNames nf
1032+ , "id" .=? (fromNetworkID <$> networkFilterIDs nf)
1033+ , "driver" .=? (fromNetworkMode <$> networkFilterDrivers nf)
1034+ , "scope" .=? (fromNetworkScope <$> networkFilterScopes nf)
1035+ , "type" .=? (fromNetworkType <$> networkFilterTypes nf)
1036+ , "label" .=? (constructLabel <$> networkFilterLabels nf)
1040+ k .=? l = Just $ k .= l
1042+constructLabel :: (Text, Maybe Text) -> Text
1043+constructLabel (k, Just v) = T.concat [k, "=", v]
1044+constructLabel (k, Nothing) = k
1046+defaultNetworkFilter :: NetworkFilter
1047+defaultNetworkFilter = NetworkFilter [] [] [] [] [] []
1049+data ConnectConfig = ConnectConfig
1050+ { connectContainer :: Text
1051+ , connectEndpointConfig :: EndpointSettings
1052+ } deriving (Eq, Show, Generic)
1054+instance ToJSON ConnectConfig where
1055+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 7 }
1057+defaultConnectConfig :: Text -> ConnectConfig
1058+defaultConnectConfig = flip ConnectConfig defaultEndpointSettings
1060+data DisconnectConfig = DisconnectConfig
1061+ { disconnectContainer :: Text
1062+ , disconnectForce :: Bool
1063+ } deriving (Eq, Show, Generic)
1065+instance ToJSON DisconnectConfig where
1066+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 10 }
1068+defaultDisconnectConfig :: Text -> DisconnectConfig
1069+defaultDisconnectConfig = flip DisconnectConfig False
1071+data PruneFilter = PruneFilter
1072+ { pruneFilterUntil :: Maybe Text
1073+ -- ^ Can be a Unix timestamp, a date-formatted timestamp, or a duration,
1074+ -- such as @10m@ or @1h30m@.
1075+ , pruneFilterIncludeLabels :: [(Text, (Maybe Text))]
1076+ , pruneFilterExcludeLabels :: [(Text, (Maybe Text))]
1077+ } deriving (Eq, Show)
1079+instance ToJSON PruneFilter where
1080+ toJSON pf = object . catMaybes $
1081+ [ "until" .=? maybeToList (pruneFilterUntil pf)
1082+ , "label" .=? (constructLabel <$> pruneFilterIncludeLabels pf)
1083+ , "label!" .=? (constructLabel <$> pruneFilterExcludeLabels pf)
1087+ k .=? l = Just $ k .= l
1089+defaultPruneFilter :: PruneFilter
1090+defaultPruneFilter = PruneFilter Nothing [] []
1092+newtype NetworksDeleted = NetworksDeleted [Text]
1093+ deriving (Eq, Show)
1095+instance FromJSON NetworksDeleted where
1096+ parseJSON (JSON.Object o) =
1097+ NetworksDeleted . join . maybeToList <$> o .: "NetworksDeleted"
1098+ parseJSON _ = fail $ "NetworksDeleted is not an object"
1100+data EndpointSettings = EndpointSettings
1101+ { endpointIPAMConfig :: IPAMSettings
1102+ , endpointLinks :: [Text]
1103+ , endpointAliases :: [Text]
1104+ , endpointNetworkID :: Maybe Text
1105+ , endpointEndpointID :: Maybe Text
1106+ , endpointGateway :: Maybe Text
1107+ , endpointIPAddress :: Maybe Text
1108+ , endpointIPPrefixLen :: Maybe Int
1109+ , endpointIPv6Gateway :: Maybe Text
1110+ , endpointGlobalIPv6Address :: Maybe Text
1111+ , endpointGlobalIPv6PrefixLen :: Maybe Int
1112+ , endpointMacAddress :: Maybe Text
1113+ } deriving (Eq, Show, Generic)
1115+instance ToJSON EndpointSettings where
1116+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 8 }
1118+defaultEndpointSettings :: EndpointSettings
1119+defaultEndpointSettings = EndpointSettings defaultIPAMSettings [] [] Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1121+data IPAMSettings = IPAMSettings
1122+ { ipamIPv4Address :: Maybe Text
1123+ , ipamIPv6Address :: Maybe Text
1124+ , ipamLinkLocalIPs :: [Text]
1125+ } deriving (Eq, Show, Generic)
1127+instance ToJSON IPAMSettings where
1128+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 4 }
1130+defaultIPAMSettings :: IPAMSettings
1131+defaultIPAMSettings = IPAMSettings Nothing Nothing []
861-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
1133-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
862-- | Set permissions on volumes that you mount in the container.
1134-- | Set permissions on volumes that you mount in the container.
863data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
1135data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
@@ -1027,11 +1299,14 @@ instance FromJSON NetworkMode where
1027 parseJSON (JSON.String n) = return $ NetworkNamed n
1299 parseJSON (JSON.String n) = return $ NetworkNamed n
1028 parseJSON _ = fail "Unknown NetworkMode"
1300 parseJSON _ = fail "Unknown NetworkMode"
1302+fromNetworkMode :: NetworkMode -> Text
1303+fromNetworkMode NetworkBridge = "bridge"
1304+fromNetworkMode NetworkHost = "host"
1305+fromNetworkMode NetworkDisabled = "none"
1306+fromNetworkMode (NetworkNamed n) = n
1030instance ToJSON NetworkMode where
1308instance ToJSON NetworkMode where
1031− toJSON NetworkBridge = JSON.String "bridge"
1309+ toJSON = JSON.String . fromNetworkMode
1032− toJSON NetworkHost = JSON.String "host"
1033− toJSON NetworkDisabled = JSON.String "none"
1034− toJSON (NetworkNamed n) = JSON.String n
1036newtype NetworkID = NetworkID Text
1311newtype NetworkID = NetworkID Text
1037 deriving (Eq, Show)
1312 deriving (Eq, Show)