@@ -76,6 +76,24 @@ module Docker.Client.Types (
76 , HostConfig(..)
76 , HostConfig(..)
77 , defaultHostConfig
77 , defaultHostConfig
78 , NetworkingConfig(..)
78 , NetworkingConfig(..)
84+ , NetworkContainer(..)
90+ , defaultConnectConfig
91+ , DisconnectConfig(..)
92+ , defaultDisconnectConfig
93+ , EndpointSettings(..)
94+ , defaultEndpointSettings
96+ , defaultIPAMSettings
79 , EndpointConfig(..)
97 , EndpointConfig(..)
80 , Ulimit(..)
98 , Ulimit(..)
81 , ContainerResources(..)
99 , ContainerResources(..)
@@ -114,6 +132,7 @@ import qualified Data.Text as T
114import Data.Time.Clock (UTCTime)
132import Data.Time.Clock (UTCTime)
115import qualified Data.Vector as V
133import qualified Data.Vector as V
116import GHC.Generics (Generic)
134import GHC.Generics (Generic)
135+import Numeric (readDec)
117import Prelude hiding (all, tail)
136import Prelude hiding (all, tail)
118import Text.Read (readMaybe)
137import Text.Read (readMaybe)
@@ -139,6 +158,10 @@ data Endpoint =
139 | DeleteImageEndpoint ImageDeleteOpts ImageID
158 | DeleteImageEndpoint ImageDeleteOpts ImageID
140 | CreateNetworkEndpoint CreateNetworkOpts
159 | CreateNetworkEndpoint CreateNetworkOpts
141 | RemoveNetworkEndpoint NetworkID
160 | RemoveNetworkEndpoint NetworkID
161+ | ListNetworksEndpoint [NetworkFilter]
162+ | InspectNetworkEndpoint NetworkID
163+ | ConnectNetworkEndpoint NetworkID ConnectConfig
164+ | DisconnectNetworkEndpoint NetworkID DisconnectConfig
142 deriving (Eq, Show)
165 deriving (Eq, Show)
144-- | We should newtype this
167-- | We should newtype this
@@ -858,6 +881,209 @@ instance ToJSON CreateNetworkOpts where
858 , "EnableIPv6" .= createNetworkEnableIPv6 opts
881 , "EnableIPv6" .= createNetworkEnableIPv6 opts
884+data NetworkScope = LocalScope | GlobalScope | SwarmScope deriving (Eq, Show)
886+fromNetworkScope :: NetworkScope -> Text
887+fromNetworkScope LocalScope = "local"
888+fromNetworkScope GlobalScope = "global"
889+fromNetworkScope SwarmScope = "swarm"
891+instance ToJSON NetworkScope where
892+ toJSON = JSON.String . fromNetworkScope
894+instance FromJSON NetworkScope where
895+ parseJSON "local" = return LocalScope
896+ parseJSON "global" = return GlobalScope
897+ parseJSON "swarm" = return SwarmScope
898+ parseJSON _ = fail "Failed to parse NetworkScope"
900+data CIDR = CIDR Text Int deriving (Eq, Show)
902+instance FromJSON CIDR where
903+ parseJSON (JSON.String t) = case T.splitOn "/" t of
904+ [a,p] -> CIDR a <$> parsePrefixLen p
905+ _ -> fail "Failed to parse CIDR"
907+ parsePrefixLen p = case readDec (T.unpack p) of
908+ (n,""):_ -> return n
909+ _ -> fail "Failed to parse CIDR prefix length"
910+ parseJSON _ = fail "Failed to parse CIDR"
912+data IPAMDriver = DefaultIPAMDriver | NamedIPAMDriver Text deriving (Eq, Show)
914+instance FromJSON IPAMDriver where
915+ parseJSON (JSON.String "default") = return DefaultIPAMDriver
916+ parseJSON (JSON.String t) = return $ NamedIPAMDriver t
917+ parseJSON _ = fail "IPAMDriver is not a string"
919+data IPAMConfig = IPAMConfig
920+ { ipamConfigSubnet :: CIDR
921+ , ipamConfigIPRange :: Maybe CIDR
922+ , ipamSubnetGateway :: Maybe Text
923+ , ipamConfigAuxAddress :: Maybe Text
924+ } deriving (Eq, Show)
926+instance FromJSON IPAMConfig where
927+ parseJSON (JSON.Object o) = IPAMConfig
931+ <*> o .:? "AuxAddress"
932+ parseJSON _ = fail "IPAMConfig is not an object"
935+ { ipamDriver :: IPAMDriver
936+ , ipamConfig :: [IPAMConfig]
937+ , ipamOptions :: HM.HashMap Text Text
938+ } deriving (Eq, Show)
940+instance FromJSON IPAM where
941+ parseJSON (JSON.Object o) = IPAM
942+ <$> o .:? "Driver" .!= DefaultIPAMDriver
943+ <*> o .:? "Config" .!= []
944+ <*> o .:? "Options" .!= HM.empty
945+ parseJSON _ = fail "IPAM is not an object"
947+data NetworkContainer = NetworkContainer
948+ { networkContainerName :: ContainerName
949+ , networkContainerEndpointID :: Text
950+ , networkContainerMacAddress :: Text
951+ , networkContainerIPv4Address :: Text
952+ , networkContainerIPv6Address :: Text
953+ } deriving (Eq, Show)
955+instance FromJSON NetworkContainer where
956+ parseJSON (JSON.Object o) = NetworkContainer
958+ <*> o .: "EndpointID"
959+ <*> o .: "MacAddress"
960+ <*> o .: "IPv4Address"
961+ <*> o .: "IPv6Address"
962+ parseJSON _ = fail "NetworkContainer is not an object"
964+data NetworkDetails = NetworkDetails
965+ { networkDetailsName :: Text
966+ , networkDetailsID :: NetworkID
967+ , networkDetailsCreated :: UTCTime
968+ , networkDetailsScope :: NetworkScope
969+ , networkDetailsDriver :: NetworkMode
970+ , networkDetailsEnableIPv6 :: Bool
971+ , networkDetailsInternal :: Bool
972+ , networkDetailsAttachable :: Bool
973+ , networkDetailsIngress :: Bool
974+ , networkDetailsIPAM :: IPAM
975+ , networkDetailsOptions :: HM.HashMap Text Text
976+ , networkDetailsLabels :: HM.HashMap Text Text
977+ , networkDetailsContainers :: HM.HashMap Text NetworkContainer
978+ } deriving (Eq, Show)
980+instance FromJSON NetworkDetails where
981+ parseJSON v@(JSON.Object o) = NetworkDetails
987+ <*> o .: "EnableIPv6"
989+ <*> o .: "Attachable"
992+ <*> o .:? "Options" .!= HM.empty
993+ <*> o .:? "Labels" .!= HM.empty
994+ <*> o .:? "Containers" .!= HM.empty
995+ parseJSON _ = fail "NetworkDetails is not an object"
997+data NetworkType = BuiltinNetwork | CustomNetwork deriving (Eq, Show)
999+fromNetworkType :: NetworkType -> Text
1000+fromNetworkType BuiltinNetwork = "builtin"
1001+fromNetworkType CustomNetwork = "custom"
1003+type NetworkName = Text
1005+instance ToJSON NetworkType where
1006+ toJSON = JSON.String . fromNetworkType
1008+instance FromJSON NetworkType where
1009+ parseJSON (JSON.String "builtin") = return BuiltinNetwork
1010+ parseJSON (JSON.String "custom") = return CustomNetwork
1011+ parseJSON _ = fail "Failed to parse NetworkType"
1014+ = NetworkFilterName Text
1015+ | NetworkFilterID NetworkID
1016+ | NetworkFilterLabel Text
1017+ | NetworkFilterDriver NetworkMode
1018+ | NetworkFilterScope NetworkScope
1019+ | NetworkFilterType NetworkType
1020+ deriving (Eq, Show)
1022+instance {-# OVERLAPPING #-} ToJSON [NetworkFilter] where
1023+ toJSON = object . fmap toKV
1025+ toKV (NetworkFilterName n) = "name" .= [n]
1026+ toKV (NetworkFilterID i) = "id" .= [fromNetworkID i]
1027+ toKV (NetworkFilterLabel l) = "label" .= [l]
1028+ toKV (NetworkFilterDriver d) = "driver" .= [fromNetworkMode d]
1029+ toKV (NetworkFilterScope s) = "scope" .= [fromNetworkScope s]
1030+ toKV (NetworkFilterType t) = "type" .= [fromNetworkType t]
1032+data ConnectConfig = ConnectConfig
1033+ { connectContainer :: Text
1034+ , connectEndpointConfig :: EndpointSettings
1035+ } deriving (Eq, Show, Generic)
1037+instance ToJSON ConnectConfig where
1038+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 7 }
1040+defaultConnectConfig :: Text -> ConnectConfig
1041+defaultConnectConfig = flip ConnectConfig defaultEndpointSettings
1043+data DisconnectConfig = DisconnectConfig
1044+ { disconnectContainer :: Text
1045+ , disconnectForce :: Bool
1046+ } deriving (Eq, Show, Generic)
1048+instance ToJSON DisconnectConfig where
1049+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 10 }
1051+defaultDisconnectConfig :: Text -> DisconnectConfig
1052+defaultDisconnectConfig = flip DisconnectConfig False
1054+data EndpointSettings = EndpointSettings
1055+ { endpointIPAMConfig :: IPAMSettings
1056+ , endpointLinks :: [Text]
1057+ , endpointAliases :: [Text]
1058+ , endpointNetworkID :: Maybe Text
1059+ , endpointEndpointID :: Maybe Text
1060+ , endpointGateway :: Maybe Text
1061+ , endpointIPAddress :: Maybe Text
1062+ , endpointIPPrefixLen :: Maybe Int
1063+ , endpointIPv6Gateway :: Maybe Text
1064+ , endpointGlobalIPv6Address :: Maybe Text
1065+ , endpointGlobalIPv6PrefixLen :: Maybe Int
1066+ , endpointMacAddress :: Maybe Text
1067+ } deriving (Eq, Show, Generic)
1069+instance ToJSON EndpointSettings where
1070+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 8 }
1072+defaultEndpointSettings :: EndpointSettings
1073+defaultEndpointSettings = EndpointSettings defaultIPAMSettings [] [] Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1075+data IPAMSettings = IPAMSettings
1076+ { ipamIPv4Address :: Maybe Text
1077+ , ipamIPv6Address :: Maybe Text
1078+ , ipamLinkLocalIPs :: [Text]
1079+ } deriving (Eq, Show, Generic)
1081+instance ToJSON IPAMSettings where
1082+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 4 }
1084+defaultIPAMSettings :: IPAMSettings
1085+defaultIPAMSettings = IPAMSettings Nothing Nothing []
861-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
1087-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
862-- | Set permissions on volumes that you mount in the container.
1088-- | Set permissions on volumes that you mount in the container.
863data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
1089data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
@@ -1027,11 +1253,14 @@ instance FromJSON NetworkMode where
1027 parseJSON (JSON.String n) = return $ NetworkNamed n
1253 parseJSON (JSON.String n) = return $ NetworkNamed n
1028 parseJSON _ = fail "Unknown NetworkMode"
1254 parseJSON _ = fail "Unknown NetworkMode"
1256+fromNetworkMode :: NetworkMode -> Text
1257+fromNetworkMode NetworkBridge = "bridge"
1258+fromNetworkMode NetworkHost = "host"
1259+fromNetworkMode NetworkDisabled = "none"
1260+fromNetworkMode (NetworkNamed n) = n
1030instance ToJSON NetworkMode where
1262instance ToJSON NetworkMode where
1031− toJSON NetworkBridge = JSON.String "bridge"
1263+ 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
1265newtype NetworkID = NetworkID Text
1037 deriving (Eq, Show)
1266 deriving (Eq, Show)
@@ -1564,11 +1793,7 @@ instance FromJSON ContainerConfig where
1564 macAddress labels stopSignal
1793 macAddress labels stopSignal
1565 parseJSON _ = fail "NetworkSettings is not an object."
1794 parseJSON _ = fail "NetworkSettings is not an object."
1567−#if MIN_VERSION_base(4,13,0)
1568−parseIntegerText :: (MonadFail m) => Text -> m Integer
1570parseIntegerText :: (Monad m) => Text -> m Integer
1796parseIntegerText :: (Monad m) => Text -> m Integer
1572parseIntegerText t = case readMaybe $ T.unpack t of
1797parseIntegerText t = case readMaybe $ T.unpack t of
1573 Nothing ->
1798 Nothing ->
1574 fail "Could not parse Integer"
1799 fail "Could not parse Integer"