module Aws.Ec2.InstanceMetadata where

import           Control.Applicative
import           Control.Exception
import           Control.Monad.Trans.Resource (throwM)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as B8
import           Data.ByteString.Lazy.UTF8 as BU
import           Data.Typeable
import qualified Network.HTTP.Conduit as HTTP
import           Prelude

data InstanceMetadataException
  = MetadataNotFound String
  deriving (Int -> InstanceMetadataException -> ShowS
[InstanceMetadataException] -> ShowS
InstanceMetadataException -> String
(Int -> InstanceMetadataException -> ShowS)
-> (InstanceMetadataException -> String)
-> ([InstanceMetadataException] -> ShowS)
-> Show InstanceMetadataException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InstanceMetadataException] -> ShowS
$cshowList :: [InstanceMetadataException] -> ShowS
show :: InstanceMetadataException -> String
$cshow :: InstanceMetadataException -> String
showsPrec :: Int -> InstanceMetadataException -> ShowS
$cshowsPrec :: Int -> InstanceMetadataException -> ShowS
Show, Typeable)

instance Exception InstanceMetadataException

getInstanceMetadata :: HTTP.Manager -> String -> String -> IO L.ByteString
getInstanceMetadata :: Manager -> String -> String -> IO ByteString
getInstanceMetadata Manager
mgr String
p String
x = do
    Request
req <- String -> IO Request
forall (m :: * -> *). MonadThrow m => String -> m Request
HTTP.parseUrlThrow (String
"http://169.254.169.254/" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
p String -> ShowS
forall a. [a] -> [a] -> [a]
++ Char
'/' Char -> ShowS
forall a. a -> [a] -> [a]
: String
x)
    Response ByteString -> ByteString
forall body. Response body -> body
HTTP.responseBody (Response ByteString -> ByteString)
-> IO (Response ByteString) -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Request -> Manager -> IO (Response ByteString)
forall (m :: * -> *).
MonadIO m =>
Request -> Manager -> m (Response ByteString)
HTTP.httpLbs Request
req Manager
mgr

getInstanceMetadataListing :: HTTP.Manager -> String -> IO [String]
getInstanceMetadataListing :: Manager -> String -> IO [String]
getInstanceMetadataListing Manager
mgr String
p = (ByteString -> String) -> [ByteString] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> String
BU.toString ([ByteString] -> [String])
-> (ByteString -> [ByteString]) -> ByteString -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ByteString -> [ByteString]
B8.split Char
'\n' (ByteString -> [String]) -> IO ByteString -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Manager -> String -> String -> IO ByteString
getInstanceMetadata Manager
mgr String
p String
""

getInstanceMetadataFirst :: HTTP.Manager -> String -> IO L.ByteString
getInstanceMetadataFirst :: Manager -> String -> IO ByteString
getInstanceMetadataFirst Manager
mgr String
p = do [String]
listing <- Manager -> String -> IO [String]
getInstanceMetadataListing Manager
mgr String
p
                                    case [String]
listing of
                                      [] -> InstanceMetadataException -> IO ByteString
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (String -> InstanceMetadataException
MetadataNotFound String
p)
                                      (String
x:[String]
_) -> Manager -> String -> String -> IO ByteString
getInstanceMetadata Manager
mgr String
p String
x

getInstanceMetadataOrFirst :: HTTP.Manager -> String -> Maybe String -> IO L.ByteString
getInstanceMetadataOrFirst :: Manager -> String -> Maybe String -> IO ByteString
getInstanceMetadataOrFirst Manager
mgr String
p (Just String
x) = Manager -> String -> String -> IO ByteString
getInstanceMetadata Manager
mgr String
p String
x
getInstanceMetadataOrFirst Manager
mgr String
p Maybe String
Nothing = Manager -> String -> IO ByteString
getInstanceMetadataFirst Manager
mgr String
p