@@ -76,6 +76,22 @@ module Docker.Client.Types (
76 , HostConfig(..)
76 , HostConfig(..)
77 , defaultHostConfig
77 , defaultHostConfig
78 , NetworkingConfig(..)
78 , NetworkingConfig(..)
84+ , NetworkContainer(..)
90+ , defaultConnectConfig
91+ , EndpointSettings(..)
92+ , defaultEndpointSettings
94+ , defaultIPAMSettings
79 , EndpointConfig(..)
95 , EndpointConfig(..)
80 , Ulimit(..)
96 , Ulimit(..)
81 , ContainerResources(..)
97 , ContainerResources(..)
@@ -114,6 +130,7 @@ import qualified Data.Text as T
114import Data.Time.Clock (UTCTime)
130import Data.Time.Clock (UTCTime)
115import qualified Data.Vector as V
131import qualified Data.Vector as V
116import GHC.Generics (Generic)
132import GHC.Generics (Generic)
133+import Numeric (readDec)
117import Prelude hiding (all, tail)
134import Prelude hiding (all, tail)
118import Text.Read (readMaybe)
135import Text.Read (readMaybe)
@@ -139,6 +156,9 @@ data Endpoint =
139 | DeleteImageEndpoint ImageDeleteOpts ImageID
156 | DeleteImageEndpoint ImageDeleteOpts ImageID
140 | CreateNetworkEndpoint CreateNetworkOpts
157 | CreateNetworkEndpoint CreateNetworkOpts
141 | RemoveNetworkEndpoint NetworkID
158 | RemoveNetworkEndpoint NetworkID
159+ | ListNetworksEndpoint [NetworkFilter]
160+ | InspectNetworkEndpoint NetworkID
161+ | ConnectNetworkEndpoint NetworkID ConnectConfig
142 deriving (Eq, Show)
162 deriving (Eq, Show)
144-- | We should newtype this
164-- | We should newtype this
@@ -858,6 +878,198 @@ instance ToJSON CreateNetworkOpts where
858 , "EnableIPv6" .= createNetworkEnableIPv6 opts
878 , "EnableIPv6" .= createNetworkEnableIPv6 opts
881+data NetworkScope = LocalScope | GlobalScope | SwarmScope deriving (Eq, Show)
883+fromNetworkScope :: NetworkScope -> Text
884+fromNetworkScope LocalScope = "local"
885+fromNetworkScope GlobalScope = "global"
886+fromNetworkScope SwarmScope = "swarm"
888+instance ToJSON NetworkScope where
889+ toJSON = JSON.String . fromNetworkScope
891+instance FromJSON NetworkScope where
892+ parseJSON "local" = return LocalScope
893+ parseJSON "global" = return GlobalScope
894+ parseJSON "swarm" = return SwarmScope
895+ parseJSON _ = fail "Failed to parse NetworkScope"
897+data CIDR = CIDR Text Int deriving (Eq, Show)
899+instance FromJSON CIDR where
900+ parseJSON (JSON.String t) = case T.splitOn "/" t of
901+ [a,p] -> CIDR a <$> parsePrefixLen p
902+ _ -> fail "Failed to parse CIDR"
904+ parsePrefixLen p = case readDec (T.unpack p) of
905+ (n,""):_ -> return n
906+ _ -> fail "Failed to parse CIDR prefix length"
907+ parseJSON _ = fail "Failed to parse CIDR"
909+data IPAMDriver = DefaultIPAMDriver | NamedIPAMDriver Text deriving (Eq, Show)
911+instance FromJSON IPAMDriver where
912+ parseJSON (JSON.String "default") = return DefaultIPAMDriver
913+ parseJSON (JSON.String t) = return $ NamedIPAMDriver t
914+ parseJSON _ = fail "IPAMDriver is not a string"
916+data IPAMConfig = IPAMConfig
917+ { ipamConfigSubnet :: CIDR
918+ , ipamConfigIPRange :: Maybe CIDR
919+ , ipamSubnetGateway :: Maybe Text
920+ , ipamConfigAuxAddress :: Maybe Text
921+ } deriving (Eq, Show)
923+instance FromJSON IPAMConfig where
924+ parseJSON (JSON.Object o) = IPAMConfig
928+ <*> o .:? "AuxAddress"
929+ parseJSON _ = fail "IPAMConfig is not an object"
932+ { ipamDriver :: IPAMDriver
933+ , ipamConfig :: [IPAMConfig]
934+ , ipamOptions :: HM.HashMap Text Text
935+ } deriving (Eq, Show)
937+instance FromJSON IPAM where
938+ parseJSON (JSON.Object o) = IPAM
939+ <$> o .:? "Driver" .!= DefaultIPAMDriver
940+ <*> o .:? "Config" .!= []
941+ <*> o .:? "Options" .!= HM.empty
942+ parseJSON _ = fail "IPAM is not an object"
944+data NetworkContainer = NetworkContainer
945+ { networkContainerName :: ContainerName
946+ , networkContainerEndpointID :: Text
947+ , networkContainerMacAddress :: Text
948+ , networkContainerIPv4Address :: Text
949+ , networkContainerIPv6Address :: Text
950+ } deriving (Eq, Show)
952+instance FromJSON NetworkContainer where
953+ parseJSON (JSON.Object o) = NetworkContainer
955+ <*> o .: "EndpointID"
956+ <*> o .: "MacAddress"
957+ <*> o .: "IPv4Address"
958+ <*> o .: "IPv6Address"
959+ parseJSON _ = fail "NetworkContainer is not an object"
961+data NetworkDetails = NetworkDetails
962+ { networkDetailsName :: Text
963+ , networkDetailsID :: NetworkID
964+ , networkDetailsCreated :: UTCTime
965+ , networkDetailsScope :: NetworkScope
966+ , networkDetailsDriver :: NetworkMode
967+ , networkDetailsEnableIPv6 :: Bool
968+ , networkDetailsInternal :: Bool
969+ , networkDetailsAttachable :: Bool
970+ , networkDetailsIngress :: Bool
971+ , networkDetailsIPAM :: IPAM
972+ , networkDetailsOptions :: HM.HashMap Text Text
973+ , networkDetailsLabels :: HM.HashMap Text Text
974+ , networkDetailsContainers :: HM.HashMap Text NetworkContainer
975+ } deriving (Eq, Show)
977+instance FromJSON NetworkDetails where
978+ parseJSON v@(JSON.Object o) = NetworkDetails
984+ <*> o .: "EnableIPv6"
986+ <*> o .: "Attachable"
989+ <*> o .:? "Options" .!= HM.empty
990+ <*> o .:? "Labels" .!= HM.empty
991+ <*> o .:? "Containers" .!= HM.empty
992+ parseJSON _ = fail "NetworkDetails is not an object"
994+data NetworkType = BuiltinNetwork | CustomNetwork deriving (Eq, Show)
996+fromNetworkType :: NetworkType -> Text
997+fromNetworkType BuiltinNetwork = "builtin"
998+fromNetworkType CustomNetwork = "custom"
1000+type NetworkName = Text
1002+instance ToJSON NetworkType where
1003+ toJSON = JSON.String . fromNetworkType
1005+instance FromJSON NetworkType where
1006+ parseJSON (JSON.String "builtin") = return BuiltinNetwork
1007+ parseJSON (JSON.String "custom") = return CustomNetwork
1008+ parseJSON _ = fail "Failed to parse NetworkType"
1011+ = NetworkFilterName Text
1012+ | NetworkFilterID NetworkID
1013+ | NetworkFilterLabel Text
1014+ | NetworkFilterDriver NetworkMode
1015+ | NetworkFilterScope NetworkScope
1016+ | NetworkFilterType NetworkType
1017+ deriving (Eq, Show)
1019+instance {-# OVERLAPPING #-} ToJSON [NetworkFilter] where
1020+ toJSON = object . fmap toKV
1022+ toKV (NetworkFilterName n) = "name" .= [n]
1023+ toKV (NetworkFilterID i) = "id" .= [fromNetworkID i]
1024+ toKV (NetworkFilterLabel l) = "label" .= [l]
1025+ toKV (NetworkFilterDriver d) = "driver" .= [fromNetworkMode d]
1026+ toKV (NetworkFilterScope s) = "scope" .= [fromNetworkScope s]
1027+ toKV (NetworkFilterType t) = "type" .= [fromNetworkType t]
1029+data ConnectConfig = ConnectConfig
1030+ { connectContainer :: Text
1031+ , connectEndpointConfig :: EndpointSettings
1032+ } deriving (Eq, Show, Generic)
1034+instance ToJSON ConnectConfig where
1035+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 7 }
1037+defaultConnectConfig :: Text -> ConnectConfig
1038+defaultConnectConfig = flip ConnectConfig defaultEndpointSettings
1040+data EndpointSettings = EndpointSettings
1041+ { endpointIPAMConfig :: IPAMSettings
1042+ , endpointLinks :: [Text]
1043+ , endpointAliases :: [Text]
1044+ , endpointNetworkID :: Maybe Text
1045+ , endpointEndpointID :: Maybe Text
1046+ , endpointGateway :: Maybe Text
1047+ , endpointIPAddress :: Maybe Text
1048+ , endpointIPPrefixLen :: Maybe Int
1049+ , endpointIPv6Gateway :: Maybe Text
1050+ , endpointGlobalIPv6Address :: Maybe Text
1051+ , endpointGlobalIPv6PrefixLen :: Maybe Int
1052+ , endpointMacAddress :: Maybe Text
1053+ } deriving (Eq, Show, Generic)
1055+instance ToJSON EndpointSettings where
1056+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 8 }
1058+defaultEndpointSettings :: EndpointSettings
1059+defaultEndpointSettings = EndpointSettings defaultIPAMSettings [] [] Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1061+data IPAMSettings = IPAMSettings
1062+ { ipamIPv4Address :: Maybe Text
1063+ , ipamIPv6Address :: Maybe Text
1064+ , ipamLinkLocalIPs :: [Text]
1065+ } deriving (Eq, Show, Generic)
1067+instance ToJSON IPAMSettings where
1068+ toJSON = genericToJSON defaultOptions { fieldLabelModifier = drop 4 }
1070+defaultIPAMSettings :: IPAMSettings
1071+defaultIPAMSettings = IPAMSettings Nothing Nothing []
861-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
1073-- TOOD: Add support for SELinux Volume labels (eg. "ro,z" or "ro/Z")
862-- | Set permissions on volumes that you mount in the container.
1074-- | Set permissions on volumes that you mount in the container.
863data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
1075data VolumePermission = ReadWrite | ReadOnly deriving (Eq, Show, Generic)
@@ -1027,11 +1239,14 @@ instance FromJSON NetworkMode where
1027 parseJSON (JSON.String n) = return $ NetworkNamed n
1239 parseJSON (JSON.String n) = return $ NetworkNamed n
1028 parseJSON _ = fail "Unknown NetworkMode"
1240 parseJSON _ = fail "Unknown NetworkMode"
1242+fromNetworkMode :: NetworkMode -> Text
1243+fromNetworkMode NetworkBridge = "bridge"
1244+fromNetworkMode NetworkHost = "host"
1245+fromNetworkMode NetworkDisabled = "none"
1246+fromNetworkMode (NetworkNamed n) = n
1030instance ToJSON NetworkMode where
1248instance ToJSON NetworkMode where
1031− toJSON NetworkBridge = JSON.String "bridge"
1249+ 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
1251newtype NetworkID = NetworkID Text
1037 deriving (Eq, Show)
1252 deriving (Eq, Show)
@@ -1564,11 +1779,7 @@ instance FromJSON ContainerConfig where
1564 macAddress labels stopSignal
1779 macAddress labels stopSignal
1565 parseJSON _ = fail "NetworkSettings is not an object."
1780 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
1782parseIntegerText :: (Monad m) => Text -> m Integer
1572parseIntegerText t = case readMaybe $ T.unpack t of
1783parseIntegerText t = case readMaybe $ T.unpack t of
1573 Nothing ->
1784 Nothing ->
1574 fail "Could not parse Integer"
1785 fail "Could not parse Integer"