Skip to content

Commit

Permalink
refactor: add and populate various IPv4/6 info to server definition
Browse files Browse the repository at this point in the history
  • Loading branch information
vst committed Apr 30, 2024
1 parent e11e1a1 commit d2cce89
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
34 changes: 32 additions & 2 deletions src/Clompse/Providers/Aws.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ import qualified Data.Conduit as C
import qualified Data.Conduit.List as CL
import Data.Int (Int16, Int32)
import qualified Data.List as L
import Data.Maybe (catMaybes, fromMaybe)
import Data.Maybe (catMaybes, fromMaybe, mapMaybe, maybeToList)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import GHC.Float (double2Int)
import GHC.Generics (Generic)
import qualified Zamazingo.Net as Z.Net
import qualified Zamazingo.Text as Z.Text


Expand Down Expand Up @@ -283,6 +284,7 @@ ec2InstanceToServer region [email protected]' {..} =
, Types._serverProvider = Types.ProviderAws
, Types._serverRegion = Aws.fromRegion region
, Types._serverType = Just (Aws.Ec2.fromInstanceType instanceType)
, Types._serverIpInfo = ec2InstanceToServerIpInfo i
}


Expand All @@ -298,6 +300,18 @@ ec2InstanceToServerState Aws.Ec2.Types.InstanceState' {..} =
_ -> Types.StateUnknown


ec2InstanceToServerIpInfo :: Aws.Ec2.Instance -> Types.ServerIpInfo
ec2InstanceToServerIpInfo Aws.Ec2.Instance' {..} =
Types.ServerIpInfo
{ _serverIpInfoStaticIpv4 = [] -- TODO: This is now reported below in public v4 field.
, _serverIpInfoStaticIpv6 = [] -- TODO: Is there such thing for AWS EC2?
, _serverIpInfoPublicIpv4 = maybeToList (Z.Net.ipv4FromText =<< publicIpAddress)
, _serverIpInfoPublicIpv6 = maybeToList (Z.Net.ipv6FromText =<< ipv6Address)
, _serverIpInfoPrivateIpv4 = maybeToList (Z.Net.ipv4FromText =<< privateIpAddress)
, _serverIpInfoPrivateIpv6 = [] -- There is no such thing for AWS EC2.
}


awsEc2InstanceName
:: Aws.Ec2.Instance
-> Maybe T.Text
Expand All @@ -310,7 +324,7 @@ awsEc2InstanceName i =


lightsailInstanceToServer :: Aws.Region -> Aws.Lightsail.Instance -> Types.Server
lightsailInstanceToServer region Aws.Lightsail.Types.Instance' {..} =
lightsailInstanceToServer region i@Aws.Lightsail.Types.Instance' {..} =
Types.Server
{ Types._serverId = fromMaybe "<unknown>" arn
, Types._serverName = name
Expand All @@ -322,6 +336,7 @@ lightsailInstanceToServer region Aws.Lightsail.Types.Instance' {..} =
, Types._serverProvider = Types.ProviderAws
, Types._serverRegion = Aws.fromRegion region
, Types._serverType = bundleId
, Types._serverIpInfo = lightsailInstanceToServerIpInfo i
}


Expand Down Expand Up @@ -352,6 +367,21 @@ lightsailInstanceToServerState Aws.Lightsail.Types.InstanceState' {..} =
_ -> Types.StateUnknown


lightsailInstanceToServerIpInfo :: Aws.Lightsail.Instance -> Types.ServerIpInfo
lightsailInstanceToServerIpInfo Aws.Lightsail.Instance' {..} =
let hasStatic = fromMaybe False isStaticIp
static4 = if hasStatic then publicIpAddress else Nothing
public4 = if hasStatic then Nothing else publicIpAddress
in Types.ServerIpInfo
{ _serverIpInfoStaticIpv4 = maybeToList (Z.Net.ipv4FromText =<< static4)
, _serverIpInfoStaticIpv6 = [] -- TODO: Is there such thing for AWS Lightsail?
, _serverIpInfoPublicIpv4 = maybeToList (Z.Net.ipv4FromText =<< public4)
, _serverIpInfoPublicIpv6 = mapMaybe Z.Net.ipv6FromText (fromMaybe [] ipv6Addresses)
, _serverIpInfoPrivateIpv4 = maybeToList (Z.Net.ipv4FromText =<< privateIpAddress)
, _serverIpInfoPrivateIpv6 = [] -- TODO: Is there such thing for AWS Lightsail?
}


-- ** Others


Expand Down
21 changes: 20 additions & 1 deletion src/Clompse/Providers/Do.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import Control.Monad.IO.Class (MonadIO)
import qualified Data.Aeson as Aeson
import qualified Data.ByteString.Lazy as BL
import Data.Int (Int16, Int32, Int64)
import qualified Data.List as List
import Data.Maybe (fromMaybe)
import Data.Scientific (Scientific)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
Expand Down Expand Up @@ -405,7 +407,7 @@ doListFirewalls conn =


toServer :: DoDroplet -> Types.Server
toServer DoDroplet {..} =
toServer droplet@DoDroplet {..} =
Types.Server
{ _serverId = Z.Text.tshow _doDropletId
, _serverName = Just _doDropletName
Expand All @@ -417,9 +419,26 @@ toServer DoDroplet {..} =
, _serverProvider = Types.ProviderDo
, _serverRegion = _doRegionSlug _doDropletRegion
, _serverType = Just _doDropletSizeSlug
, _serverIpInfo = toServerIpInfo droplet
}


toServerIpInfo :: DoDroplet -> Types.ServerIpInfo
toServerIpInfo DoDroplet {..} =
let nets4 = fromMaybe [] (_doNetworksV4 _doDropletNetworks)
nets6 = fromMaybe [] (_doNetworksV6 _doDropletNetworks)
ipv4s = fmap ((,) <$> _doNetworkV4IpAddress <*> _doNetworkV4Type) nets4
ipv6s = fmap ((,) <$> _doNetworkV6IpAddress <*> _doNetworkV6Type) nets6
in Types.ServerIpInfo
{ _serverIpInfoStaticIpv4 = [] -- TODO: For now, reserved IP is seen in public IP section below.
, _serverIpInfoStaticIpv6 = [] -- No such thing for DO.
, _serverIpInfoPublicIpv4 = List.nub [ip | (ip, "public") <- ipv4s]
, _serverIpInfoPublicIpv6 = List.nub [ip | (ip, "public") <- ipv6s]
, _serverIpInfoPrivateIpv4 = List.nub [ip | (ip, "private") <- ipv4s]
, _serverIpInfoPrivateIpv6 = List.nub [ip | (ip, "private") <- ipv6s]
}


toServerState :: T.Text -> Types.State
toServerState "new" = Types.StateCreating
toServerState "active" = Types.StateRunning
Expand Down
18 changes: 16 additions & 2 deletions src/Clompse/Providers/Hetzner.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import Control.Monad.IO.Class (MonadIO)
import qualified Data.Aeson as Aeson
import Data.Int (Int16, Int32)
import qualified Data.List as List
import Data.Maybe (mapMaybe)
import Data.Maybe (mapMaybe, maybeToList)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import qualified Data.Time as Time
import GHC.Generics (Generic)
import qualified Hetzner.Cloud as Hetzner
import qualified Zamazingo.Net as Z.Net
import qualified Zamazingo.Text as Z.Text


Expand Down Expand Up @@ -102,7 +103,7 @@ hetznerListServersWithFirewalls conn = do


toServer :: Hetzner.Server -> Types.Server
toServer Hetzner.Server {..} =
toServer srv@Hetzner.Server {..} =
Types.Server
{ Types._serverId = toServerId serverID
, Types._serverName = Just serverName
Expand All @@ -114,6 +115,19 @@ toServer Hetzner.Server {..} =
, Types._serverProvider = Types.ProviderHetzner
, Types._serverRegion = Hetzner.locationName . Hetzner.datacenterLocation $ serverDatacenter
, Types._serverType = Just (Hetzner.serverTypeDescription serverType)
, Types._serverIpInfo = toServerIpInfo srv
}


toServerIpInfo :: Hetzner.Server -> Types.ServerIpInfo
toServerIpInfo Hetzner.Server {..} =
Types.ServerIpInfo
{ _serverIpInfoStaticIpv4 = [] -- TODO: hetzner library does not provide this information.
, _serverIpInfoStaticIpv6 = [] -- TODO: hetzner library does not provide this information.
, _serverIpInfoPrivateIpv4 = [] -- TODO: hetzner library does not provide this information.
, _serverIpInfoPrivateIpv6 = [] -- TODO: hetzner library does not provide this information.
, _serverIpInfoPublicIpv4 = maybeToList (Z.Net.MkIPv4 . Hetzner.publicIP <$> Hetzner.publicIPv4 serverPublicNetwork)
, _serverIpInfoPublicIpv6 = foldMap (fmap (Z.Net.MkIPv6 . Hetzner.publicIP) . Hetzner.reverseDNS) (Hetzner.publicIPv6 serverPublicNetwork)
}


Expand Down
31 changes: 31 additions & 0 deletions src/Clompse/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import qualified Data.Time as Time
import GHC.Generics (Generic)
import qualified Zamazingo.Net as Z.Net


-- $setup
Expand Down Expand Up @@ -123,6 +124,7 @@ data Server = Server
, _serverProvider :: !Provider
, _serverRegion :: !T.Text
, _serverType :: !(Maybe T.Text)
, _serverIpInfo :: !ServerIpInfo
}
deriving (Eq, Generic, Show)
deriving (Aeson.FromJSON, Aeson.ToJSON) via (ADC.Autodocodec Server)
Expand All @@ -145,3 +147,32 @@ instance ADC.HasCodec Server where
<*> ADC.requiredField "provider" "Cloud provider." ADC..= _serverProvider
<*> ADC.requiredField "region" "Region." ADC..= _serverRegion
<*> ADC.optionalField "type" "Server type." ADC..= _serverType
<*> ADC.requiredField "ip_info" "Server IP addresses information." ADC..= _serverIpInfo


-- | Server IP addresses information.
data ServerIpInfo = ServerIpInfo
{ _serverIpInfoStaticIpv4 :: ![Z.Net.IPv4]
, _serverIpInfoStaticIpv6 :: ![Z.Net.IPv6]
, _serverIpInfoPublicIpv4 :: ![Z.Net.IPv4]
, _serverIpInfoPublicIpv6 :: ![Z.Net.IPv6]
, _serverIpInfoPrivateIpv4 :: ![Z.Net.IPv4]
, _serverIpInfoPrivateIpv6 :: ![Z.Net.IPv6]
}
deriving (Eq, Generic, Show)
deriving (Aeson.FromJSON, Aeson.ToJSON) via (ADC.Autodocodec ServerIpInfo)


instance ADC.HasCodec ServerIpInfo where
codec =
_codec ADC.<?> "Server IP Addresses Information"
where
_codec =
ADC.object "ServerIpInfo" $
ServerIpInfo
<$> ADC.requiredField "static_ipv4" "Static IPv4 addresses." ADC..= _serverIpInfoStaticIpv4
<*> ADC.requiredField "static_ipv6" "Static IPv6 addresses." ADC..= _serverIpInfoStaticIpv6
<*> ADC.requiredField "public_ipv4" "Public IPv4 addresses." ADC..= _serverIpInfoPublicIpv4
<*> ADC.requiredField "public_ipv6" "Public IPv6 addresses." ADC..= _serverIpInfoPublicIpv6
<*> ADC.requiredField "private_ipv4" "Private IPv4 addresses." ADC..= _serverIpInfoPrivateIpv4
<*> ADC.requiredField "private_ipv6" "Private IPv6 addresses." ADC..= _serverIpInfoPrivateIpv6

0 comments on commit d2cce89

Please sign in to comment.